rubymotionr 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. data/.gitignore +2 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +24 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +31 -0
  7. data/Rakefile +1 -0
  8. data/lib/rubymotionr.rb +7 -0
  9. data/lib/rubymotionr/project.rb +18 -0
  10. data/lib/rubymotionr/repo.rb +18 -0
  11. data/lib/rubymotionr/version.rb +3 -0
  12. data/rubymotionr.gemspec +19 -0
  13. data/spec/.DS_Store +0 -0
  14. data/spec/multiple-rubymotion-apps/Beers/README +5 -0
  15. data/spec/multiple-rubymotion-apps/Beers/Rakefile +8 -0
  16. data/spec/multiple-rubymotion-apps/Beers/app/app_delegate.rb +16 -0
  17. data/spec/multiple-rubymotion-apps/Beers/app/beer.rb +22 -0
  18. data/spec/multiple-rubymotion-apps/Beers/app/beer_details_controller.rb +15 -0
  19. data/spec/multiple-rubymotion-apps/Beers/app/beer_list_controller.rb +40 -0
  20. data/spec/multiple-rubymotion-apps/Beers/app/beer_map_controller.rb +51 -0
  21. data/spec/multiple-rubymotion-apps/Beers/resources/.gitignore +0 -0
  22. data/spec/multiple-rubymotion-apps/Beers/resources/list.png +0 -0
  23. data/spec/multiple-rubymotion-apps/Beers/resources/map.png +0 -0
  24. data/spec/multiple-rubymotion-apps/CircleLayout/.gitignore +5 -0
  25. data/spec/multiple-rubymotion-apps/CircleLayout/README +5 -0
  26. data/spec/multiple-rubymotion-apps/CircleLayout/Rakefile +9 -0
  27. data/spec/multiple-rubymotion-apps/CircleLayout/app/app_delegate.rb +8 -0
  28. data/spec/multiple-rubymotion-apps/CircleLayout/app/cell.rb +13 -0
  29. data/spec/multiple-rubymotion-apps/CircleLayout/app/circle_layout.rb +41 -0
  30. data/spec/multiple-rubymotion-apps/CircleLayout/app/view_controller.rb +33 -0
  31. data/spec/multiple-rubymotion-apps/Fonts/README +7 -0
  32. data/spec/multiple-rubymotion-apps/Fonts/Rakefile +8 -0
  33. data/spec/multiple-rubymotion-apps/Fonts/app/app_delegate.rb +9 -0
  34. data/spec/multiple-rubymotion-apps/Fonts/app/detail_controller.rb +50 -0
  35. data/spec/multiple-rubymotion-apps/Fonts/app/root_controller.rb +65 -0
  36. data/spec/multiple-rubymotion-apps/Fonts/resources/.gitkeep +0 -0
  37. data/spec/multiple-rubymotion-apps/GestureTable/README +8 -0
  38. data/spec/multiple-rubymotion-apps/GestureTable/Rakefile +8 -0
  39. data/spec/multiple-rubymotion-apps/GestureTable/app/UIColor_extensions.rb +32 -0
  40. data/spec/multiple-rubymotion-apps/GestureTable/app/UITableView_extensions.rb +7 -0
  41. data/spec/multiple-rubymotion-apps/GestureTable/app/app_delegate.rb +9 -0
  42. data/spec/multiple-rubymotion-apps/GestureTable/app/gesture_recognizer.rb +361 -0
  43. data/spec/multiple-rubymotion-apps/GestureTable/app/transformable_cells.rb +92 -0
  44. data/spec/multiple-rubymotion-apps/GestureTable/app/view_controller.rb +173 -0
  45. data/spec/multiple-rubymotion-apps/GestureTable/resources/.gitignore +0 -0
  46. data/spec/multiple-rubymotion-apps/Hello/README +3 -0
  47. data/spec/multiple-rubymotion-apps/Hello/Rakefile +8 -0
  48. data/spec/multiple-rubymotion-apps/Hello/app/app_delegate.rb +9 -0
  49. data/spec/multiple-rubymotion-apps/Hello/app/hello_view.rb +33 -0
  50. data/spec/multiple-rubymotion-apps/Hello/app/hello_view_controller.rb +5 -0
  51. data/spec/multiple-rubymotion-apps/Hello/resources/.gitignore +0 -0
  52. data/spec/multiple-rubymotion-apps/Hello/resources/icon.png +0 -0
  53. data/spec/multiple-rubymotion-apps/HelloGL/README +9 -0
  54. data/spec/multiple-rubymotion-apps/HelloGL/Rakefile +11 -0
  55. data/spec/multiple-rubymotion-apps/HelloGL/app/app_delegate.rb +16 -0
  56. data/spec/multiple-rubymotion-apps/HelloGL/app/index_data.rb +19 -0
  57. data/spec/multiple-rubymotion-apps/HelloGL/app/motiongl_controller.rb +139 -0
  58. data/spec/multiple-rubymotion-apps/HelloGL/app/vertex_data.rb +22 -0
  59. data/spec/multiple-rubymotion-apps/HelloGL/resources/rubymotion.png +0 -0
  60. data/spec/multiple-rubymotion-apps/Locations/README +3 -0
  61. data/spec/multiple-rubymotion-apps/Locations/Rakefile +8 -0
  62. data/spec/multiple-rubymotion-apps/Locations/app/app_delegate.rb +11 -0
  63. data/spec/multiple-rubymotion-apps/Locations/app/location.rb +21 -0
  64. data/spec/multiple-rubymotion-apps/Locations/app/locations_controller.rb +66 -0
  65. data/spec/multiple-rubymotion-apps/Locations/app/locations_store.rb +61 -0
  66. data/spec/multiple-rubymotion-apps/Locations/resources/.gitignore +0 -0
  67. data/spec/multiple-rubymotion-apps/Mustache/README +5 -0
  68. data/spec/multiple-rubymotion-apps/Mustache/Rakefile +10 -0
  69. data/spec/multiple-rubymotion-apps/Mustache/app/app_delegate.rb +9 -0
  70. data/spec/multiple-rubymotion-apps/Mustache/app/mustache_view_controller.rb +99 -0
  71. data/spec/multiple-rubymotion-apps/Mustache/resources/.gitignore +0 -0
  72. data/spec/multiple-rubymotion-apps/Mustache/resources/guido.jpg +0 -0
  73. data/spec/multiple-rubymotion-apps/Mustache/resources/jmccolor.jpg +0 -0
  74. data/spec/multiple-rubymotion-apps/Mustache/resources/kay.jpg +0 -0
  75. data/spec/multiple-rubymotion-apps/Mustache/resources/matz.jpg +0 -0
  76. data/spec/multiple-rubymotion-apps/Mustache/resources/mustache.png +0 -0
  77. data/spec/multiple-rubymotion-apps/Paint/README +3 -0
  78. data/spec/multiple-rubymotion-apps/Paint/Rakefile +8 -0
  79. data/spec/multiple-rubymotion-apps/Paint/app/app_delegate.rb +9 -0
  80. data/spec/multiple-rubymotion-apps/Paint/app/paint_view.rb +57 -0
  81. data/spec/multiple-rubymotion-apps/Paint/app/paint_view_controller.rb +13 -0
  82. data/spec/multiple-rubymotion-apps/Paint/resources/.gitignore +0 -0
  83. data/spec/multiple-rubymotion-apps/Paint/resources/erase.caf +0 -0
  84. data/spec/multiple-rubymotion-apps/PaintHTML/README +8 -0
  85. data/spec/multiple-rubymotion-apps/PaintHTML/Rakefile +10 -0
  86. data/spec/multiple-rubymotion-apps/PaintHTML/app/app_delegate.rb +10 -0
  87. data/spec/multiple-rubymotion-apps/PaintHTML/app/web_view_controller.rb +48 -0
  88. data/spec/multiple-rubymotion-apps/PaintHTML/resources/index.html +211 -0
  89. data/spec/multiple-rubymotion-apps/PaintHTML/resources/index2.html +14 -0
  90. data/spec/multiple-rubymotion-apps/README.rdoc +47 -0
  91. data/spec/multiple-rubymotion-apps/StoryboardCustoms/README.md +42 -0
  92. data/spec/multiple-rubymotion-apps/StoryboardCustoms/Rakefile +7 -0
  93. data/spec/multiple-rubymotion-apps/StoryboardCustoms/app/app_delegate.rb +12 -0
  94. data/spec/multiple-rubymotion-apps/StoryboardCustoms/app/custom_view_controller1.rb +31 -0
  95. data/spec/multiple-rubymotion-apps/StoryboardCustoms/app/custom_view_controller2.rb +29 -0
  96. data/spec/multiple-rubymotion-apps/StoryboardCustoms/app/helpers.rb +4 -0
  97. data/spec/multiple-rubymotion-apps/StoryboardCustoms/resources/Master.storyboard +127 -0
  98. data/spec/multiple-rubymotion-apps/TicTacToe/.gitignore +5 -0
  99. data/spec/multiple-rubymotion-apps/TicTacToe/Rakefile +7 -0
  100. data/spec/multiple-rubymotion-apps/TicTacToe/app/app_delegate.rb +8 -0
  101. data/spec/multiple-rubymotion-apps/TicTacToe/app/board.rb +59 -0
  102. data/spec/multiple-rubymotion-apps/TicTacToe/app/board_view_controller.rb +86 -0
  103. data/spec/multiple-rubymotion-apps/Timer/README +3 -0
  104. data/spec/multiple-rubymotion-apps/Timer/Rakefile +7 -0
  105. data/spec/multiple-rubymotion-apps/Timer/app/app_delegate.rb +9 -0
  106. data/spec/multiple-rubymotion-apps/Timer/app/timer_controller.rb +38 -0
  107. data/spec/multiple-rubymotion-apps/Timer/resources/.gitignore +0 -0
  108. data/spec/multiple-rubymotion-apps/Trollify/README +6 -0
  109. data/spec/multiple-rubymotion-apps/Trollify/Rakefile +9 -0
  110. data/spec/multiple-rubymotion-apps/Trollify/app/app_delegate.rb +9 -0
  111. data/spec/multiple-rubymotion-apps/Trollify/app/image_composition_controller.rb +193 -0
  112. data/spec/multiple-rubymotion-apps/Trollify/app/uiimage_extension.rb +27 -0
  113. data/spec/multiple-rubymotion-apps/Trollify/resources/.gitignore +0 -0
  114. data/spec/multiple-rubymotion-apps/Trollify/resources/ballmer.jpg +0 -0
  115. data/spec/multiple-rubymotion-apps/Trollify/resources/icon.png +0 -0
  116. data/spec/multiple-rubymotion-apps/Trollify/resources/icon@2x.png +0 -0
  117. data/spec/multiple-rubymotion-apps/Trollify/resources/trollface.png +0 -0
  118. data/spec/multiple-rubymotion-apps/Tweets/README +3 -0
  119. data/spec/multiple-rubymotion-apps/Tweets/Rakefile +7 -0
  120. data/spec/multiple-rubymotion-apps/Tweets/app/app_delegate.rb +9 -0
  121. data/spec/multiple-rubymotion-apps/Tweets/app/data_parser.rb +10 -0
  122. data/spec/multiple-rubymotion-apps/Tweets/app/json_parser.rb +12 -0
  123. data/spec/multiple-rubymotion-apps/Tweets/app/tweet.rb +11 -0
  124. data/spec/multiple-rubymotion-apps/Tweets/app/tweet_cell.rb +51 -0
  125. data/spec/multiple-rubymotion-apps/Tweets/app/tweets_controller.rb +72 -0
  126. data/spec/multiple-rubymotion-apps/Tweets/resources/.gitignore +0 -0
  127. data/spec/repo_spec.rb +27 -0
  128. data/spec/rubymotion-example/.DS_Store +0 -0
  129. data/spec/rubymotion-example/README +3 -0
  130. data/spec/rubymotion-example/Rakefile +7 -0
  131. data/spec/rubymotion-example/app/app_delegate.rb +9 -0
  132. data/spec/rubymotion-example/app/data_parser.rb +10 -0
  133. data/spec/rubymotion-example/app/json_parser.rb +12 -0
  134. data/spec/rubymotion-example/app/tweet.rb +11 -0
  135. data/spec/rubymotion-example/app/tweet_cell.rb +51 -0
  136. data/spec/rubymotion-example/app/tweets_controller.rb +72 -0
  137. data/spec/rubymotion-example/resources/.gitignore +0 -0
  138. data/spec/spec_helper.rb +9 -0
  139. metadata +309 -0
@@ -0,0 +1,7 @@
1
+ Fonts.app
2
+
3
+ This sample demonstrates the following concepts: Table View, Accessory View, Fonts.
4
+
5
+ This sample was contributed by Samuel Chandra.
6
+
7
+ https://github.com/samchandra/Fonts
@@ -0,0 +1,8 @@
1
+ $:.unshift("/Library/RubyMotion/lib")
2
+ require 'motion/project'
3
+
4
+ Motion::Project::App.setup do |app|
5
+ # Use `rake config' to see complete project settings.
6
+ app.name = 'Fonts'
7
+ app.frameworks += ['QuartzCore']
8
+ end
@@ -0,0 +1,9 @@
1
+ class AppDelegate
2
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
3
+ @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
4
+ @window.rootViewController = UINavigationController.alloc.initWithRootViewController(RootController.alloc.init)
5
+ @window.rootViewController.wantsFullScreenLayout = true
6
+ @window.makeKeyAndVisible
7
+ true
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ class DetailController < UIViewController
2
+ def loadView
3
+ self.view = UIScrollView.alloc.initWithFrame(UIScreen.mainScreen.applicationFrame)
4
+ view.autoresizingMask = UIViewAutoresizingFlexibleHeight
5
+ view.autoresizesSubviews = true
6
+ view.backgroundColor = UIColor.whiteColor
7
+
8
+ @text_label = UILabel.alloc.init
9
+ @text_label.numberOfLines = 0
10
+ view.addSubview(@text_label)
11
+ end
12
+
13
+ def viewDidLoad
14
+ navigationItem.title = "Sample Text"
15
+ end
16
+
17
+ def viewDidAppear(animated)
18
+ font = UIFont.fontWithName(@font_name, size:16)
19
+ frame_size = sample_text.sizeWithFont(font, constrainedToSize:[self.view.bounds.size.width - 20, 1000], lineBreakMode:UILineBreakModeWordWrap)
20
+ rect = [[10, 10], [frame_size.width, frame_size.height]]
21
+
22
+ @text_label.text = sample_text
23
+ @text_label.frame = rect
24
+ @text_label.font = font
25
+
26
+ view.contentSize = [self.view.frame.size.width, frame_size.height + 20]
27
+ end
28
+
29
+ def selected_font(font_name)
30
+ @font_name = font_name
31
+ end
32
+
33
+ def sample_text
34
+ <<EOS
35
+ #{@font_name}
36
+
37
+ RubyMotion offers developers the expressiveness of Ruby with no compromises. It's hard to imagine a more appealing way to build native iOS applications.
38
+
39
+ This is AWESOME! With just minimal iOS experience, I was able to get a working app up and running on my phone. Oh, the feeling of power!
40
+
41
+ RubyMotion is a dream come true for Rubyists who want to create fast, native iOS apps!
42
+
43
+ Now you can develop in your favorite language on your favorite mobile platform. Done right. For real. What are you waiting for?
44
+
45
+ With RubyMotion, we can now leverage our Ruby expertise to solve problems in the mobile space. Developing for iOS will never be the same again.
46
+
47
+ After years of iOS work, RubyMotion seems like a thousand kittens playing the piano while sliding down a double-rainbow.
48
+ EOS
49
+ end
50
+ end
@@ -0,0 +1,65 @@
1
+ class RootController < UITableViewController
2
+ def viewDidLoad
3
+ view.dataSource = view.delegate = self
4
+ navigationItem.title = "Fonts"
5
+ end
6
+
7
+ def numberOfSectionsInTableView(tableView)
8
+ fonts.count
9
+ end
10
+
11
+ def tableView(tableView, titleForHeaderInSection:section)
12
+ fonts[section][:family]
13
+ end
14
+
15
+ def sectionIndexTitlesForTableView(tableView)
16
+ fonts.map do |e|
17
+ e[:family].slice(0)
18
+ end.uniq
19
+ end
20
+
21
+ def tableView(tableView, sectionForSectionIndexTitle:title, atIndex:index)
22
+ fonts.map do |e|
23
+ e[:family].slice(0)
24
+ end.index(title)
25
+ end
26
+
27
+ def tableView(tableView, numberOfRowsInSection:section)
28
+ fonts[section][:fonts].count
29
+ end
30
+
31
+ CELLID = "fonts"
32
+ def tableView(tableView, cellForRowAtIndexPath:indexPath)
33
+ cell = tableView.dequeueReusableCellWithIdentifier(CELLID) || begin
34
+ cell = UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:CELLID)
35
+ cell.selectionStyle = UITableViewCellSelectionStyleBlue
36
+ cell
37
+ end
38
+
39
+ font_dict = fonts[indexPath.section]
40
+ font_name = font_dict[:fonts][indexPath.row]
41
+ cell.textLabel.font = UIFont.fontWithName(font_name, size:18)
42
+ cell.textLabel.text = font_name
43
+ cell
44
+ end
45
+
46
+ def tableView(tableView, didSelectRowAtIndexPath:indexPath)
47
+ font_dict = fonts[indexPath.section]
48
+ font_name = font_dict[:fonts][indexPath.row]
49
+
50
+ @detail_controller ||= DetailController.alloc.init
51
+ @detail_controller.selected_font(font_name)
52
+ self.navigationController.pushViewController(@detail_controller, animated:true)
53
+
54
+ tableView.deselectRowAtIndexPath(indexPath, animated:true)
55
+ end
56
+
57
+ def fonts
58
+ @fonts ||= begin
59
+ UIFont.familyNames.sort.map do |family|
60
+ fonts = UIFont.fontNamesForFamilyName(family).sort
61
+ {:family => family, :fonts => fonts}
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,8 @@
1
+ Gesture Table.app
2
+
3
+ This sample demonstrates a table view that interacts with gestures as found in the Clear iPhone app. http://www.realmacsoftware.com/clear
4
+
5
+ The code of this sample was originally a Ruby translation of the following
6
+ Objective-C project: https://github.com/mystcolor/JTGestureBasedTableViewDemo
7
+
8
+ Initial port was done by Josh Ballanco <jballanc@gmail.com>.
@@ -0,0 +1,8 @@
1
+ $:.unshift("/Library/RubyMotion/lib")
2
+ require 'motion/project'
3
+
4
+ Motion::Project::App.setup do |app|
5
+ # Use `rake config' to see complete project settings.
6
+ app.name = 'Gesture Table'
7
+ app.frameworks += ['QuartzCore']
8
+ end
@@ -0,0 +1,32 @@
1
+ class UIColor
2
+ def colorWithBrightness(brightnessComponent)
3
+ hue = Pointer.new(:float)
4
+ saturation = Pointer.new(:float)
5
+ brightness = Pointer.new(:float)
6
+ red = Pointer.new(:float)
7
+ green = Pointer.new(:float)
8
+ blue = Pointer.new(:float)
9
+ white = Pointer.new(:float)
10
+ alpha = Pointer.new(:float)
11
+
12
+ if getHue(hue, saturation: saturation, brightness: brightness, alpha: alpha)
13
+ UIColor.colorWithHue(hue[0], saturation: saturation[0], brightness: brightness[0] * brightnessComponent, alpha: alpha[0])
14
+ elsif getRed(red, green: green, blue: blue, alpha: alpha)
15
+ UIColor.colorWithRed(red[0] * brightnessComponent, green: green[0] * brightnessComponent, blue: blue[0] * brightnessComponent, alpha: alpha[0])
16
+ elsif getWhite(white, alpha: alpha)
17
+ UIColor.colorWithWhite(white[0] * brightnessComponent, alpha: alpha[0])
18
+ end
19
+ end
20
+
21
+ def colorWithHueOffset(hueOffset)
22
+ hue = Pointer.new(:float)
23
+ saturation = Pointer.new(:float)
24
+ brightness = Pointer.new(:float)
25
+ alpha = Pointer.new(:float)
26
+
27
+ if getHue(hue, saturation: saturation, brightness: brightness, alpha: alpha)
28
+ newHue = (hue[0] + hueOffset) % 1
29
+ UIColor.colorWithHue(newHue, saturation: saturation[0], brightness: brightness[0], alpha: alpha[0])
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ class UITableView
2
+ def reloadVisibleRowsExceptIndexPath(indexPath)
3
+ visibleRows = indexPathsForVisibleRows.mutableCopy
4
+ visibleRows.removeObject(indexPath)
5
+ reloadRowsAtIndexPaths(visibleRows, withRowAnimation: UITableViewRowAnimationNone)
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ class AppDelegate
2
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
3
+ application.setStatusBarStyle(UIStatusBarStyleBlackOpaque)
4
+ @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
5
+ @window.rootViewController = UINavigationController.alloc.initWithRootViewController(ViewController.new)
6
+ @window.makeKeyAndVisible
7
+ true
8
+ end
9
+ end
@@ -0,0 +1,361 @@
1
+ class GestureRecognizer
2
+ CommitEditingRowDefaultRowHeight = 80
3
+ RowAnimationDuration = 0.25
4
+ CellSnapshotTag = 100000
5
+
6
+ def initWithTableView(tableView, delegate:delegate)
7
+ if init
8
+ @tableView = tableView
9
+ @delegate= delegate
10
+ @state = :none
11
+ @tableViewDelegate = tableView.delegate
12
+ tableView.delegate = self
13
+
14
+ @pinchRecognizer = UIPinchGestureRecognizer.alloc.initWithTarget(self, action: :"pinchGestureRecognizer:")
15
+ @panRecognizer = UIPanGestureRecognizer.alloc.initWithTarget(self, action: :"panGestureRecognizer:")
16
+ @longPressRecognizer = UILongPressGestureRecognizer.alloc.initWithTarget(self, action: :"longPressGestureRecognizer:")
17
+ tableView.gestureRecognizers += [@pinchRecognizer, @panRecognizer, @longPressRecognizer]
18
+ @pinchRecognizer.delegate = @panRecognizer.delegate = @longPressRecognizer.delegate = self
19
+ @addingRowHeight = 0
20
+ end
21
+ self
22
+ end
23
+
24
+ def scrollTable
25
+ location = @longPressRecognizer.locationInView(@tableView)
26
+
27
+ currentOffset = @tableView.contentOffset
28
+ @scrollingRate ||= 0
29
+ newOffset = CGPointMake(currentOffset.x, currentOffset.y + @scrollingRate)
30
+ if newOffset.y < 0
31
+ newOffset.y = 0
32
+ elsif @tableView.contentSize.height < @tableView.frame.size.height
33
+ newOffset = currentOffset
34
+ elsif newOffset.y > @tableView.contentSize.height - @tableView.frame.size.height
35
+ newOffset.y = @tableView.contentSize.height - @tableView.frame.size.height
36
+ end
37
+ @tableView.setContentOffset(newOffset)
38
+
39
+ if location.y >= 0
40
+ cellSnapshotView = @tableView.viewWithTag(CellSnapshotTag)
41
+ cellSnapshotView.center = CGPointMake(@tableView.center.x, location.y)
42
+ end
43
+
44
+ updateAddingIndexPathForCurrentLocation
45
+ end
46
+
47
+ def updateAddingIndexPathForCurrentLocation
48
+ indexPath = indexPathFromRecognizer(@longPressRecognizer)
49
+ if indexPath && indexPath != @addingIndexPath
50
+ @tableView.beginUpdates
51
+ @tableView.deleteRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationNone)
52
+ @tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
53
+ @delegate.gestureRecognizer(self, needsMoveRowAtIndexPath: @addingIndexPath, toIndexPath: indexPath)
54
+ @tableView.endUpdates
55
+ @addingIndexPath = indexPath
56
+ end
57
+ end
58
+
59
+ def commitOrDiscardCell
60
+ @tableView.beginUpdates
61
+
62
+ cell = @tableView.cellForRowAtIndexPath(@addingIndexPath)
63
+ commitingCellHeight =
64
+ if @delegate.respond_to? :"gestureRecognizer:heightForCommittingRowAtIndexPath:"
65
+ @delegate.gestureRecognizer(self, heightForCommittingRowAtIndexPath: @addingIndexPath)
66
+ else
67
+ @tableView.rowHeight
68
+ end
69
+ if cell.frame.size.height >= commitingCellHeight
70
+ @delegate.gestureRecognizer(self, needsCommitRowAtIndexPath: @addingIndexPath)
71
+ else
72
+ @delegate.gestureRecognizer(self, needsDiscardRowAtIndexPath: @addingIndexPath)
73
+ @tableView.deleteRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationMiddle)
74
+ end
75
+
76
+ @tableView.performSelector(:"reloadVisibleRowsExceptIndexPath:", withObject: @addingIndexPath, afterDelay: RowAnimationDuration)
77
+ @addingIndexPath = nil
78
+
79
+ @tableView.endUpdates
80
+
81
+ UIView.beginAnimations('', context: nil)
82
+ UIView.setAnimationBeginsFromCurrentState(true)
83
+ UIView.setAnimationDuration(0.5)
84
+ @tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
85
+ UIView.commitAnimations
86
+
87
+ @state = :none
88
+ end
89
+
90
+ def pinchGestureRecognizer(recognizer)
91
+ if recognizer.state == UIGestureRecognizerStateEnded || recognizer.numberOfTouches < 2
92
+ self.commitOrDiscardCell if @addingIndexPath
93
+ return
94
+ end
95
+
96
+ location1 = recognizer.locationOfTouch(0, inView: @tableView)
97
+ location2 = recognizer.locationOfTouch(1, inView: @tableView)
98
+ upperPoint = location1.y < location2.y ? location1 : location2
99
+
100
+ rect = CGRectMake(*location1, location2.x - location1.x, location2.y - location1.y)
101
+
102
+ if recognizer.state == UIGestureRecognizerStateBegan
103
+ @state = :pinching
104
+ indexPaths = @tableView.indexPathsForRowsInRect(rect)
105
+ unless indexPaths.empty?
106
+ midIndex = ((indexPaths.first.row + indexPaths.last.row) / 2.0) + 0.5
107
+ midIndexPath = NSIndexPath.indexPathForRow(midIndex, inSection: indexPaths.first.section)
108
+
109
+ @startPinchingUpperPoint = upperPoint
110
+
111
+ if @delegate.respond_to? :"gestureRecognizer:willCreateCellAtIndexPath:"
112
+ @addingIndexPath = @delegate.gestureRecognizer(self, willCreateCellAtIndexPath: midIndexPath)
113
+ else
114
+ @addingIndexPath = midIndexPath
115
+ end
116
+
117
+ @tableView.contentInset = UIEdgeInsetsMake(@tableView.frame.size.height, 0, @tableView.frame.size.height, 0)
118
+
119
+ if @addingIndexPath
120
+ @tableView.beginUpdates
121
+ @delegate.gestureRecognizer(self, needsAddRowAtIndexPath: @addingIndexPath)
122
+ @tableView.insertRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationMiddle)
123
+ @tableView.endUpdates
124
+ end
125
+ end
126
+ elsif recognizer.state == UIGestureRecognizerStateChanged
127
+ diffRowHeight = CGRectGetHeight(rect) - CGRectGetHeight(rect)/recognizer.scale
128
+ if @addingRowHeight - diffRowHeight >= 1 || @addingRowHeight - diffRowHeight <= -1
129
+ @addingRowHeight = diffRowHeight
130
+ @tableView.reloadData
131
+ end
132
+
133
+ newUpperPoint = upperPoint
134
+ diffOffsetY = @startPinchingUpperPoint.y - newUpperPoint.y
135
+ newOffset = CGPointMake(@tableView.contentOffset.x, @tableView.contentOffset.y + diffOffsetY)
136
+ @tableView.setContentOffset(newOffset, animated: false)
137
+ end
138
+ end
139
+
140
+ def panGestureRecognizer(recognizer)
141
+ if (recognizer.state == UIGestureRecognizerStateBegan ||
142
+ recognizer.state == UIGestureRecognizerStateChanged) &&
143
+ recognizer.numberOfTouches > 0
144
+
145
+ location1 = recognizer.locationOfTouch(0, inView: @tableView)
146
+ indexPath = @addingIndexPath
147
+ unless indexPath
148
+ indexPath = @tableView.indexPathForRowAtPoint(location1)
149
+ @addingIndexPath = indexPath
150
+ end
151
+
152
+ @state = :panning
153
+ cell = @tableView.cellForRowAtIndexPath(indexPath)
154
+ translation = recognizer.translationInView(@tableView)
155
+ cell.contentView.frame = CGRectOffset(cell.contentView.bounds, translation.x, 0)
156
+
157
+ if @delegate.respond_to? :"gestureRecognizer:didChangeContentViewTranslation:forRowAtIndexPath:"
158
+ @delegate.gestureRecognizer(self, didChangeContentViewTranslation: translation, forRowAtIndexPath: indexPath)
159
+ end
160
+
161
+ commitEditingLength = lengthForCommitEditingRowAtIndexPath(indexPath)
162
+ if translation.x.abs >= commitEditingLength
163
+ if @addingCellState == :middle
164
+ @addingCellState = translation.x > 0 ? :right : :left
165
+ end
166
+ else
167
+ if @addingCellState != :middle
168
+ @addingCellState = :middle
169
+ end
170
+ end
171
+
172
+ if @delegate.respond_to? :"gestureRecognizer:didEnterEditingState:forRowAtIndexPath:"
173
+ @delegate.gestureRecognizer(self, didEnterEditingState: @addingCellState, forRowAtIndexPath: indexPath)
174
+ end
175
+ elsif recognizer.state == UIGestureRecognizerStateEnded
176
+ cell = @tableView.cellForRowAtIndexPath(@addingIndexPath)
177
+ translation = recognizer.translationInView(@tableView)
178
+
179
+ commitEditingLength = lengthForCommitEditingRowAtIndexPath(@addingIndexPath)
180
+ if translation.x.abs >= commitEditingLength
181
+ if @delegate.respond_to? :"gestureRecognizer:commitEditingState:forRowAtIndexPath:"
182
+ @delegate.gestureRecognizer(self, commitEditingState: @addingCellState, forRowAtIndexPath: @addingIndexPath)
183
+ end
184
+ else
185
+ UIView.beginAnimations('', context: nil)
186
+ cell.contentView.frame = cell.contentView.bounds
187
+ UIView.commitAnimations
188
+ end
189
+
190
+ @addingCellState = :middle
191
+ @addingIndexPath = nil
192
+ @state = :none
193
+ end
194
+ end
195
+
196
+ def longPressGestureRecognizer(recognizer)
197
+ location = recognizer.locationInView(@tableView)
198
+ indexPath = indexPathFromRecognizer(recognizer)
199
+
200
+ case recognizer.state
201
+ when UIGestureRecognizerStateBegan
202
+ @state = :moving
203
+
204
+ cell = @tableView.cellForRowAtIndexPath(indexPath)
205
+ UIGraphicsBeginImageContextWithOptions(cell.bounds.size, false, 0)
206
+ cell.layer.renderInContext(UIGraphicsGetCurrentContext())
207
+ cellImage = UIGraphicsGetImageFromCurrentImageContext()
208
+ UIGraphicsEndImageContext()
209
+
210
+ snapShotView = @tableView.viewWithTag(CellSnapshotTag)
211
+ unless snapShotView
212
+ snapShotView = UIImageView.alloc.initWithImage(cellImage)
213
+ snapShotView.tag = CellSnapshotTag
214
+ @tableView.addSubview(snapShotView)
215
+ rect = @tableView.rectForRowAtIndexPath(indexPath)
216
+ snapShotView.frame = CGRectOffset(snapShotView.bounds, rect.origin.x, rect.origin.y)
217
+ end
218
+
219
+ UIView.beginAnimations('zoomCell', context: nil)
220
+ snapShotView.transform = CGAffineTransformMakeScale(1.1, 1.1)
221
+ snapShotView.center = CGPointMake(@tableView.center.x, location.y)
222
+ UIView.commitAnimations
223
+
224
+ @tableView.beginUpdates
225
+ @tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
226
+ @tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
227
+ @delegate.gestureRecognizer(self, needsCreatePlaceholderForRowAtIndexPath: indexPath)
228
+ @addingIndexPath = indexPath
229
+ @tableView.endUpdates
230
+
231
+ @movingTimer = NSTimer.timerWithTimeInterval((1/8.0), target: self, selector: :scrollTable, userInfo: nil, repeats: true)
232
+ NSRunLoop.mainRunLoop.addTimer(@movingTimer, forMode: NSDefaultRunLoopMode)
233
+
234
+ when UIGestureRecognizerStateEnded
235
+ snapShotView = @tableView.viewWithTag(CellSnapshotTag)
236
+ indexPath = @addingIndexPath
237
+
238
+ @movingTimer.invalidate
239
+ @movingTimer = nil
240
+ @scrollingRate = 0
241
+
242
+ UIView.animateWithDuration(RowAnimationDuration,
243
+ animations: -> do
244
+ rect = @tableView.rectForRowAtIndexPath(indexPath)
245
+ snapShotView.transform = CGAffineTransformIdentity
246
+ snapShotView.frame = CGRectOffset(snapShotView.bounds, rect.origin.x, rect.origin.y)
247
+ end,
248
+ completion: ->(finished) do
249
+ snapShotView.removeFromSuperview
250
+
251
+ @tableView.beginUpdates
252
+ @tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
253
+ @tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
254
+ @delegate.gestureRecognizer(self, needsReplacePlaceholderForRowAtIndexPath: indexPath)
255
+ @tableView.endUpdates
256
+
257
+ @tableView.reloadVisibleRowsExceptIndexPath(indexPath)
258
+ @cellSnapshot = nil
259
+ @addingIndexPath = nil
260
+ @state = :none
261
+ end)
262
+
263
+ when UIGestureRecognizerStateChanged
264
+ snapShotView = @tableView.viewWithTag(CellSnapshotTag)
265
+ snapShotView.center = CGPointMake(@tableView.center.x, location.y)
266
+
267
+ rect = @tableView.bounds
268
+ location = @longPressRecognizer.locationInView(@tableView)
269
+ location.y -= @tableView.contentOffset.y
270
+
271
+ self.updateAddingIndexPathForCurrentLocation
272
+
273
+ topDropZoneHeight = bottomDropZoneHeight = @tableView.bounds.size.height / 6.0
274
+ bottomDiff = location.y - (rect.size.height - bottomDropZoneHeight)
275
+ if bottomDiff > 0
276
+ @scrollingRate = bottomDiff / (bottomDropZoneHeight / 1)
277
+ elsif location.y <= topDropZoneHeight
278
+ @scrollingRate = -(topDropZoneHeight - [location.y, 0].max) / bottomDropZoneHeight
279
+ else
280
+ @scrollingRate = 0
281
+ end
282
+ end
283
+ end
284
+
285
+ def gestureRecognizerShouldBegin(gestureRecognizer)
286
+ indexPath = indexPathFromRecognizer(gestureRecognizer)
287
+
288
+ case gestureRecognizer
289
+ when @panRecognizer
290
+ point = gestureRecognizer.translationInView(@tableView)
291
+ if point.y.abs > point.x.abs || indexPath.nil?
292
+ false
293
+ elsif indexPath
294
+ @delegate.gestureRecognizer(self, canEditRowAtIndexPath: indexPath)
295
+ end
296
+ when @longPressRecognizer
297
+ if indexPath
298
+ @delegate.gestureRecognizer(self, canMoveRowAtIndexPath: indexPath)
299
+ else
300
+ false
301
+ end
302
+ else
303
+ true
304
+ end
305
+ end
306
+
307
+ def tableView(aTableView, heightForRowAtIndexPath: indexPath)
308
+ if indexPath == @addingIndexPath && (@state == :pinching || @state == :dragging)
309
+ [1, @addingRowHeight || 0].max
310
+ else
311
+ @tableViewDelegate.tableView(aTableView, heightForRowAtIndexPath: indexPath)
312
+ end
313
+ end
314
+
315
+ def scrollViewDidScroll(scrollView)
316
+ if scrollView.contentOffset.y < 0
317
+ if @addingIndexPath.nil? && @state == :none && !scrollView.isDecelerating
318
+ @state = :dragging
319
+ @addingIndexPath =
320
+ if @delegate.respond_to?(:"gestureRecognizer:willCreateCellAtIndexPath:")
321
+ @delegate.gestureRecognizer(self, willCreateCellAtIndexPath: @addingIndexPath)
322
+ else
323
+ NSIndexPath.indexPathForRow(0, inSection: 0)
324
+ end
325
+
326
+ @tableView.beginUpdates
327
+ @delegate.gestureRecognizer(self, needsAddRowAtIndexPath: @addingIndexPath)
328
+ @tableView.insertRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationNone)
329
+ @addingRowHeight = scrollView.contentOffset.y.abs
330
+ @tableView.endUpdates
331
+ end
332
+ end
333
+
334
+ if @state == :dragging
335
+ @addingRowHeight += scrollView.contentOffset.y * -1
336
+ @tableView.reloadData
337
+ scrollView.setContentOffset(CGPointZero)
338
+ end
339
+ end
340
+
341
+ def scrollViewDidEndDragging(scrollView, willDecelerate: decelerate)
342
+ if @state == :dragging
343
+ @state = :none
344
+ self.commitOrDiscardCell
345
+ end
346
+ end
347
+
348
+ def indexPathFromRecognizer(recognizer)
349
+ location = recognizer.locationInView(@tableView)
350
+ @tableView.indexPathForRowAtPoint(location)
351
+ end
352
+
353
+ def lengthForCommitEditingRowAtIndexPath(indexPath)
354
+ if @delegate.respond_to? :"gestureRecognizer:lengthForCommitEditingRowAtIndexPath:"
355
+ @delegate.gestureRecognizer(self, lengthForCommitEditingRowAtIndexPath: indexPath)
356
+ else
357
+ CommitEditingRowDefaultRowHeight
358
+ end
359
+ end
360
+ end
361
+