rubymotionr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+