ProMotion 2.4.2 → 2.5.0.beta1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -13
  3. data/lib/ProMotion.rb +40 -14
  4. data/lib/ProMotion/cocoatouch/collection_view_cell.rb +8 -0
  5. data/lib/ProMotion/cocoatouch/collection_view_controller.rb +49 -0
  6. data/lib/ProMotion/cocoatouch/view_controller.rb +5 -0
  7. data/lib/ProMotion/collection/cell/collection_view_cell_module.rb +17 -0
  8. data/lib/ProMotion/collection/collection.rb +106 -0
  9. data/lib/ProMotion/collection/collection_builder.rb +39 -0
  10. data/lib/ProMotion/collection/collection_class_methods.rb +38 -0
  11. data/lib/ProMotion/collection/collection_screen.rb +8 -0
  12. data/lib/ProMotion/collection/data/collection_data.rb +32 -0
  13. data/lib/ProMotion/collection/data/collection_data_builder.rb +18 -0
  14. data/lib/ProMotion/delegate/delegate_module.rb +1 -1
  15. data/lib/ProMotion/ipad/split_screen.rb +0 -1
  16. data/lib/ProMotion/repl/live_reloader.rb +76 -0
  17. data/lib/ProMotion/repl/repl.rb +65 -0
  18. data/lib/ProMotion/screen/nav_bar_module.rb +8 -1
  19. data/lib/ProMotion/screen/screen_module.rb +26 -3
  20. data/lib/ProMotion/screen/screen_navigation.rb +3 -0
  21. data/lib/ProMotion/table/cell/table_view_cell_module.rb +11 -0
  22. data/lib/ProMotion/table/extensions/searchable.rb +11 -0
  23. data/lib/ProMotion/table/table.rb +12 -1
  24. data/lib/ProMotion/table/table_builder.rb +7 -5
  25. data/lib/ProMotion/tabs/tabs.rb +6 -3
  26. data/lib/ProMotion/version.rb +1 -1
  27. data/spec/functional/func_screen_spec.rb +25 -20
  28. data/spec/functional/func_split_screen_spec.rb +2 -2
  29. data/spec/unit/collection_screen_spec.rb +133 -0
  30. data/spec/unit/screen_helpers_spec.rb +1 -1
  31. data/spec/unit/screen_spec.rb +44 -6
  32. data/spec/unit/tables/table_module_spec.rb +28 -2
  33. data/spec/unit/tables/table_refreshable_spec.rb +25 -0
  34. data/spec/unit/tables/table_screen_spec.rb +0 -56
  35. data/spec/unit/tables/table_searchable_spec.rb +41 -0
  36. data/spec/unit/tables/table_view_cell_spec.rb +20 -1
  37. metadata +22 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5b96025262856164455456dfcb5fd811c9a8b87
4
- data.tar.gz: 52861b244be201c1d8f32adcf279498cb6c4e19e
3
+ metadata.gz: 77d8dcbafac1e2b4972fc44dae533bf1c847b443
4
+ data.tar.gz: 8a7d5813a1c005b76a1354012205cd03f6845f86
5
5
  SHA512:
6
- metadata.gz: 34fcc571eb15f5b1bf90dc6b7b1abbbdd68a5babb8d910cf5ee269d87057888ca9bfd8e6ff8450e00a3335b51c435f034daaa5f21caac4c62be8a9ce25cafeff
7
- data.tar.gz: 73b3d6bbe13fded0cf3fe934c81b9b54993bb6ae5dae3f6129d209598fea510cb7a8d18e03fa5dfbc867cf4881dddc7ca6fa9cf6279685661655b4ece1cc8e63
6
+ metadata.gz: eb9181c62d284ba7e7a22ea3dd1902b284574f056e2e4c420961bf0d589b37dc2e2333d51c77de9bacb7d275e829de73c5804ff35423f83d78f30dbd72099c4c
7
+ data.tar.gz: bc025137788d5920b72e852c0b8a12545e4c49ef7fefde496ac66b293b4acc724df87e97ce3761b23002920f1a53ecf9f7560ff8cff66c1e2cf75c8beef937e4
data/README.md CHANGED
@@ -3,9 +3,6 @@
3
3
  [![Gem Version](https://img.shields.io/gem/v/ProMotion.svg?style=flat)](https://rubygems.org/gems/ProMotion)
4
4
  [![Build Status](https://img.shields.io/travis/clearsightstudio/ProMotion.svg?style=flat)](https://travis-ci.org/clearsightstudio/ProMotion)
5
5
  [![Code Climate](https://img.shields.io/codeclimate/github/clearsightstudio/ProMotion.svg?style=flat)](https://codeclimate.com/github/clearsightstudio/ProMotion)
6
- [![Dependency Status](https://img.shields.io/gemnasium/clearsightstudio/ProMotion.svg?style=flat)](https://gemnasium.com/clearsightstudio/ProMotion)
7
- [![omniref](https://img.shields.io/badge/omniref-docs-blue.svg?style=flat)](https://www.omniref.com/ruby/gems/ProMotion)
8
- [![Stories in Ready](https://badge.waffle.io/clearsightstudio/ProMotion.png?label=ready&title=Ready)](https://waffle.io/clearsightstudio/ProMotion)
9
6
 
10
7
  ## iPhone Apps, Ruby-style
11
8
 
@@ -14,23 +11,20 @@ It introduces a clean, Ruby-style syntax for building screens that is easy to le
14
11
  abstracts a ton of boilerplate UIViewController, UINavigationController, and other iOS code into a
15
12
  simple, Ruby-like DSL.
16
13
 
17
- * Watch Jamon Holmgren give a talk about ProMotion at [RubyMotion #inspect2014](http://confreaks.com/videos/3813-inspect-going-pro-with-promotion-from-prototype-to-production) (video)
18
- * Watch the [September 2013 Motion Meetup](http://www.youtube.com/watch?v=rf7h-3AiMRQ) where Gant Laborde
19
- interviews Jamon Holmgren about ProMotion
20
-
21
14
  ```ruby
22
15
  # app/app_delegate.rb
23
16
  class AppDelegate < PM::Delegate
24
17
  status_bar true, animation: :fade
25
18
 
26
19
  def on_load(app, options)
27
- open RootScreen.new(nav_bar: true)
20
+ open RootScreen
28
21
  end
29
22
  end
30
23
 
31
24
  # app/screens/root_screen.rb
32
25
  class RootScreen < PM::Screen
33
26
  title "Root Screen"
27
+ nav_bar true
34
28
 
35
29
  def on_load
36
30
  set_nav_bar_button :right, title: "Help", action: :open_help_screen
@@ -69,16 +63,18 @@ end
69
63
 
70
64
  |Screens|Navigation Bars|Tab Bars|
71
65
  |---|---|---|
72
- |[![ProMotion Screen](https://f.cloud.github.com/assets/1479215/1534021/060aaaac-4c8f-11e3-903c-743e54252222.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20Screen/)|[![ProMotion Nav Bar](https://f.cloud.github.com/assets/1479215/1534077/db39aab6-4c8f-11e3-83f7-e03d52ac615d.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20Screen/#set_nav_bar_buttonside-args)|[![ProMotion Tabs](https://f.cloud.github.com/assets/1479215/1534115/9f4c4cd8-4c90-11e3-9285-96ac253facda.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20Tabs/)|
66
+ |[![ProMotion Screen](https://f.cloud.github.com/assets/1479215/1534021/060aaaac-4c8f-11e3-903c-743e54252222.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20Screen/)|[![ProMotion Nav Bar](https://f.cloud.github.com/assets/1479215/1534077/db39aab6-4c8f-11e3-83f7-e03d52ac615d.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20Screen/#set_nav_bar_buttonside-args)|[![ProMotion Tabs](https://f.cloud.github.com/assets/1479215/1534115/9f4c4cd8-4c90-11e3-9285-96ac253facda.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20Tabs/)|
73
67
 
74
68
  |Table Screens|Grouped Tables|Searchable|Refreshable|
75
69
  |---|---|---|---|
76
- |[![ProMotion TableScreen](https://f.cloud.github.com/assets/1479215/1534137/ed71e864-4c90-11e3-98aa-ed96049f5407.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20TableScreen/)|[![Grouped Table Screen](https://f.cloud.github.com/assets/1479215/1589973/61a48610-5281-11e3-85ac-abee99bf73ad.png)](https://gist.github.com/jamonholmgren/382a6cf9963c5f0b2248)|[![Searchable](https://f.cloud.github.com/assets/1479215/1534299/20cc05c6-4c93-11e3-92ca-9ee39c044457.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20TableScreen/#searchableplaceholder-placeholder-text)|[![Refreshable](https://f.cloud.github.com/assets/1479215/1534317/5a14ef28-4c93-11e3-8e9e-f8c08d8464f8.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20TableScreen/#refreshableoptions)|
70
+ |[![ProMotion TableScreen](https://f.cloud.github.com/assets/1479215/1534137/ed71e864-4c90-11e3-98aa-ed96049f5407.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20TableScreen/)|[![Grouped Table Screen](https://f.cloud.github.com/assets/1479215/1589973/61a48610-5281-11e3-85ac-abee99bf73ad.png)](https://gist.github.com/jamonholmgren/382a6cf9963c5f0b2248)|[![Searchable](https://f.cloud.github.com/assets/1479215/1534299/20cc05c6-4c93-11e3-92ca-9ee39c044457.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20TableScreen/#searchableplaceholder-placeholder-text)|[![Refreshable](https://f.cloud.github.com/assets/1479215/1534317/5a14ef28-4c93-11e3-8e9e-f8c08d8464f8.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20TableScreen/#refreshableoptions)|
77
71
 
78
72
 
79
- |iPad SplitScreens|Map Screens|Web Screens|
73
+ |SplitScreens|Map Screens|Web Screens|
80
74
  |---|---|---|
81
- |[![ProMotion SplitScreens](https://f.cloud.github.com/assets/1479215/1534507/0edb8dd4-4c96-11e3-9896-d4583d0ed161.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20SplitScreen/)|[![MapScreen](https://f.cloud.github.com/assets/1479215/1534628/f7dbf7e8-4c97-11e3-8817-4c2a58824771.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20MapScreen/)|[![ProMotion WebScreen](https://f.cloud.github.com/assets/1479215/1534631/ffe1b36a-4c97-11e3-8c8f-c7b14e26182d.png)](http://promotion.readthedocs.org/en/master/Reference/API%20Reference%20-%20ProMotion%20WebScreen/)|
75
+ |[![ProMotion SplitScreens](https://f.cloud.github.com/assets/1479215/1534507/0edb8dd4-4c96-11e3-9896-d4583d0ed161.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20SplitScreen/)|[![MapScreen](https://f.cloud.github.com/assets/1479215/1534628/f7dbf7e8-4c97-11e3-8817-4c2a58824771.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20MapScreen/)|[![ProMotion WebScreen](https://f.cloud.github.com/assets/1479215/1534631/ffe1b36a-4c97-11e3-8c8f-c7b14e26182d.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20WebScreen/)|
76
+
77
+ **NEW** [Live reloading!](http://promotion.readthedocs.org/en/master/Guides/Live Screen Reloading/) Use `pm_live_screens` to enable it, and `on_live_reload` in your screen to refresh things.
82
78
 
83
79
  #### ...and much more.
84
80
 
@@ -123,7 +119,7 @@ This release includes several new features and is backwards compatible with all
123
119
 
124
120
  ## Your app
125
121
 
126
- Open a pull request!
122
+ Open a pull request! We love adding new ProMotion-built apps.
127
123
 
128
124
  # API Reference
129
125
 
@@ -131,6 +127,12 @@ We've created a comprehensive and always updated wiki with code examples, usage
131
127
 
132
128
  ### [ProMotion Documentation](https://github.com/clearsightstudio/ProMotion/blob/master/docs)
133
129
 
130
+ # Screencasts
131
+
132
+ * Watch Jamon Holmgren give a talk about ProMotion at [RubyMotion #inspect2014](http://confreaks.com/videos/3813-inspect-going-pro-with-promotion-from-prototype-to-production) (video)
133
+ * Watch the [September 2013 Motion Meetup](http://www.youtube.com/watch?v=rf7h-3AiMRQ) where Gant Laborde
134
+ interviews Jamon Holmgren about ProMotion
135
+
134
136
  # Help
135
137
 
136
138
  ProMotion is not only an easy DSL to get started. The community is very helpful and
data/lib/ProMotion.rb CHANGED
@@ -12,33 +12,59 @@ Motion::Project::App.setup do |app|
12
12
  app.files.insert(insert_point, file)
13
13
  end
14
14
 
15
+ app.development do
16
+ app.info_plist["ProjectRootPath"] ||= File.absolute_path(app.project_dir)
17
+ end
18
+
15
19
  # For compatibility with libraries that don't use detect_dependencies. :-(
16
20
  app.files_dependencies({
17
21
  "#{core_lib}/version.rb" => [ "#{core_lib}/pro_motion.rb" ],
18
22
  "#{core_lib}/cocoatouch/table_view_cell.rb" => [ "#{core_lib}/table/cell/table_view_cell_module.rb" ],
19
23
  "#{core_lib}/table/cell/table_view_cell_module.rb" => [ "#{core_lib}/styling/styling.rb" ],
24
+ "#{core_lib}/cocoatouch/collection_view_cell.rb" => [ "#{core_lib}/collection/cell/collection_view_cell_module.rb" ],
25
+ "#{core_lib}/collection/collection_screen.rb" => [
26
+ "#{core_lib}/screen/screen_module.rb",
27
+ "#{core_lib}/collection/cell/collection_view_cell_module.rb",
28
+ ],
29
+ "#{core_lib}/collection/cell/collection_view_cell_module.rb" => [ "#{core_lib}/styling/styling.rb" ],
20
30
  "#{core_lib}/delegate/delegate.rb" => [ "#{core_lib}/delegate/delegate_parent.rb" ],
21
31
  "#{core_lib}/delegate/delegate_parent.rb" => [ "#{core_lib}/delegate/delegate_module.rb" ],
22
32
  "#{core_lib}/delegate/delegate_module.rb" => [
23
- "#{core_lib}/support/support.rb",
24
- "#{core_lib}/tabs/tabs.rb",
25
- "#{core_lib}/ipad/split_screen.rb"
33
+ "#{core_lib}/support/support.rb",
34
+ "#{core_lib}/tabs/tabs.rb",
35
+ "#{core_lib}/ipad/split_screen.rb"
26
36
  ],
27
37
  "#{core_lib}/screen/screen.rb" => [ "#{core_lib}/screen/screen_module.rb" ],
28
- "#{core_lib}/screen/screen_module.rb" => [ "#{core_lib}/screen/screen_navigation.rb" ],
38
+ "#{core_lib}/screen/screen_navigation.rb" => [ "#{core_lib}/support/support.rb", ],
39
+ "#{core_lib}/screen/screen_module.rb" => [
40
+ "#{core_lib}/tabs/tabs.rb",
41
+ "#{core_lib}/screen/nav_bar_module.rb",
42
+ "#{core_lib}/screen/screen_navigation.rb",
43
+ "#{core_lib}/ipad/split_screen.rb",
44
+ ],
29
45
  "#{core_lib}/table/data/table_data.rb" => [
30
- "#{core_lib}/table/data/table_data_builder.rb",
31
- "#{core_lib}/table/table.rb"
46
+ "#{core_lib}/table/data/table_data_builder.rb",
47
+ "#{core_lib}/table/table.rb"
48
+ ],
49
+ "#{core_lib}/collection/data/collection_data.rb" => [
50
+ "#{core_lib}/collection/data/collection_data_builder.rb",
51
+ "#{core_lib}/collection/collection.rb",
52
+ "#{core_lib}/table/table_utils.rb"
32
53
  ],
33
54
  "#{core_lib}/table/table.rb" => [
34
- "#{core_lib}/table/table_class_methods.rb",
35
- "#{core_lib}/table/table_builder.rb",
36
- "#{core_lib}/table/table_utils.rb",
37
- "#{core_lib}/table/extensions/searchable.rb",
38
- "#{core_lib}/table/extensions/refreshable.rb",
39
- "#{core_lib}/table/extensions/indexable.rb",
40
- "#{core_lib}/table/extensions/longpressable.rb"
55
+ "#{core_lib}/table/table_class_methods.rb",
56
+ "#{core_lib}/table/table_builder.rb",
57
+ "#{core_lib}/table/table_utils.rb",
58
+ "#{core_lib}/table/extensions/searchable.rb",
59
+ "#{core_lib}/table/extensions/refreshable.rb",
60
+ "#{core_lib}/table/extensions/indexable.rb",
61
+ "#{core_lib}/table/extensions/longpressable.rb"
62
+ ],
63
+ "#{core_lib}/collection/collection.rb" => [
64
+ "#{core_lib}/collection/collection_class_methods.rb",
65
+ "#{core_lib}/collection/collection_builder.rb",
66
+ "#{core_lib}/table/table_utils.rb"
41
67
  ],
42
68
  "#{core_lib}/web/web_screen.rb" => [ "#{core_lib}/web/web_screen_module.rb" ],
43
- })
69
+ })
44
70
  end
@@ -0,0 +1,8 @@
1
+ module ProMotion
2
+ class CollectionViewCell < UICollectionViewCell
3
+ include ProMotion::CollectionViewCellModule
4
+
5
+ attr_accessor :reused
6
+ KIdentifier = '__ProMotion_CollectionViewCell'
7
+ end
8
+ end
@@ -0,0 +1,49 @@
1
+ module ProMotion
2
+ class CollectionViewController < UICollectionViewController
3
+ def self.new(args = {})
4
+ s = self.alloc.initWithCollectionViewLayout(get_collection_layout)
5
+ s.screen_init(args) if s.respond_to?(:screen_init)
6
+ s
7
+ end
8
+
9
+ def loadView
10
+ self.respond_to?(:load_view) ? self.load_view : super
11
+ end
12
+
13
+ def viewWillAppear(animated)
14
+ super
15
+ self.view_will_appear(animated) if self.respond_to?("view_will_appear:")
16
+ end
17
+
18
+ def viewDidAppear(animated)
19
+ super
20
+ self.view_did_appear(animated) if self.respond_to?("view_did_appear:")
21
+ end
22
+
23
+ def viewWillDisappear(animated)
24
+ self.view_will_disappear(animated) if self.respond_to?("view_will_disappear:")
25
+ super
26
+ end
27
+
28
+ def viewDidDisappear(animated)
29
+ self.view_did_disappear(animated) if self.respond_to?("view_did_disappear:")
30
+ super
31
+ end
32
+
33
+ def shouldAutorotateToInterfaceOrientation(orientation)
34
+ self.should_rotate(orientation)
35
+ end
36
+
37
+ def shouldAutorotate
38
+ self.should_autorotate
39
+ end
40
+
41
+ def willRotateToInterfaceOrientation(orientation, duration:duration)
42
+ self.will_rotate(orientation, duration)
43
+ end
44
+
45
+ def didRotateFromInterfaceOrientation(orientation)
46
+ self.on_rotate
47
+ end
48
+ end
49
+ end
@@ -35,6 +35,11 @@ module ProMotion
35
35
  super
36
36
  end
37
37
 
38
+ def didReceiveMemoryWarning
39
+ self.did_receive_memory_warning if self.respond_to?(:did_receive_memory_warning)
40
+ super
41
+ end
42
+
38
43
  def shouldAutorotateToInterfaceOrientation(orientation)
39
44
  self.should_rotate(orientation)
40
45
  end
@@ -0,0 +1,17 @@
1
+ module ProMotion
2
+ module CollectionViewCellModule
3
+ include ProMotion::Styling
4
+
5
+ attr_accessor :data_cell, :collection_screen
6
+
7
+ def setup(data_cell, screen)
8
+ self.collection_screen = WeakRef.new(screen)
9
+ self.data_cell = data_cell
10
+ end
11
+
12
+ def prepareForReuse
13
+ super
14
+ self.send(:prepare_for_reuse) if self.respond_to?(:prepare_for_reuse)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,106 @@
1
+ module ProMotion
2
+ module Collection
3
+ include ProMotion::Styling
4
+ include ProMotion::Table::Utils
5
+ include ProMotion::CollectionBuilder
6
+
7
+ attr_reader :promotion_collection_data
8
+
9
+ def collection_view
10
+ self.collectionView
11
+ end
12
+
13
+ def screen_setup
14
+ check_collection_data
15
+ end
16
+
17
+ # Override viewDidLoad here to register cell classes here.
18
+ # Calling it from `screen_setup` cause `on_load` to be called twice
19
+ def viewDidLoad
20
+ super
21
+ set_up_register_class
22
+ end
23
+
24
+ def set_up_register_class
25
+ collection_view.registerClass(PM::CollectionViewCell, forCellWithReuseIdentifier: PM::CollectionViewCell::KIdentifier)
26
+ if self.class.get_cell_classes
27
+ self.class.get_cell_classes.each do |identifier, klass|
28
+ collection_view.registerClass(klass, forCellWithReuseIdentifier: identifier.to_s)
29
+ end
30
+ end
31
+ end
32
+
33
+ def check_collection_data
34
+ mp("Missing #collection_data method in CollectionScreen #{self.class.to_s}.", force_color: :red) unless self.respond_to?(:collection_data)
35
+ end
36
+
37
+ def promotion_collection_data
38
+ @promotion_collection_data ||= CollectionData.new(collection_data, collection_view)
39
+ end
40
+
41
+ # Returns the data cell
42
+ def cell_at(args = {})
43
+ self.promotion_collection_data.cell(args)
44
+ end
45
+
46
+ def update_collection_view_data(data, args = {})
47
+ self.promotion_collection_data.data = data
48
+ if args[:index_paths]
49
+ collection_view.reloadItemsAtIndexPaths(Array(args[:index_paths]))
50
+ elsif args[:sections]
51
+ collection_view.reloadSections(args[:sections])
52
+ else
53
+ collection_view.reloadData
54
+ end
55
+ end
56
+
57
+ def reload_data
58
+ update_collection_view_data(collection_data)
59
+ end
60
+
61
+ ########## Cocoa touch methods #################
62
+
63
+ ## UICollectionViewDataSource ##
64
+ def collectionView(_, numberOfItemsInSection: section)
65
+ self.promotion_collection_data.section_length(section)
66
+ end
67
+
68
+ def numberOfSectionsInCollectionView(_)
69
+ self.promotion_collection_data.sections.length
70
+ end
71
+
72
+ def collectionView(_, cellForItemAtIndexPath: index_path)
73
+ params = index_path_to_section_index(index_path: index_path)
74
+ data_cell = cell_at(index: params[:index], section: params[:section])
75
+ create_collection_cell(data_cell, index_path)
76
+ end
77
+
78
+ ## UICollectionViewDelegate ##
79
+ def collectionView(view, didSelectItemAtIndexPath: index_path)
80
+ params = index_path_to_section_index(index_path: index_path)
81
+ data_cell = cell_at(index: params[:index], section: params[:section])
82
+
83
+ trigger_action(data_cell[:action], data_cell[:arguments], params) if data_cell[:action]
84
+ end
85
+
86
+ ## UICollectionViewDelegateFlowLayout ##
87
+ def collectionView(_, layout: view_layout, sizeForItemAtIndexPath: index_path)
88
+ if self.respond_to?(:size_at_index_path)
89
+ self.size_at_index_path(index_path_to_section_index(index_path: index_path))
90
+ elsif view_layout.itemSize
91
+ view_layout.itemSize
92
+ elsif view_layout.respond_to?(:estimatedItemSize) and view_layout.estimatedItemSize
93
+ view_layout.estimatedItemSize
94
+ else
95
+ mp "Implement the size_at_index_path method in your PM::CollectionScreen or add item_size or estimated_item_size in the layout options to configure the size of your cells.", force_color: :yellow
96
+ end
97
+ end
98
+
99
+ protected
100
+
101
+ def self.included(base)
102
+ base.extend(CollectionClassMethods)
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,39 @@
1
+ module ProMotion
2
+ module CollectionBuilder
3
+ def trigger_action(action, arguments, index_path)
4
+ action = (action.is_a?(Proc) ? action : method(action))
5
+ case arity = action.arity
6
+ when 0 then action.call # Just call the proc or the method
7
+ when 2 then action.call(arguments, index_path) # Send arguments and index path
8
+ else
9
+ mp("Action should not have optional parameters: #{action.to_s}", force_color: :yellow) if arity < 0
10
+ action.call(arguments) # Send arguments
11
+ end
12
+ end
13
+
14
+ def create_collection_cell(data_cell, index_path)
15
+ cell = collection_view.dequeueReusableCellWithReuseIdentifier(data_cell[:cell_identifier].to_s, forIndexPath: index_path)
16
+ cell.extend(PM::CollectionViewCellModule) unless cell.is_a?(PM::CollectionViewCellModule)
17
+ cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
18
+ cell.clipsToBounds = true
19
+ if cell.respond_to?(:reused)
20
+ if cell.reused
21
+ on_cell_reused(cell)
22
+ else
23
+ on_cell_created(cell)
24
+ cell.reused = true
25
+ end
26
+ end
27
+ cell.setup(data_cell, self) if cell.respond_to?(:setup)
28
+ cell
29
+ end
30
+
31
+ def on_cell_created(cell)
32
+ cell.send(:on_created) if cell.respond_to?(:on_created)
33
+ end
34
+
35
+ def on_cell_reused(cell)
36
+ cell.send(:on_reuse) if cell.respond_to?(:on_reuse)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ module CollectionClassMethods
2
+
3
+ def collection_layout(klass, options={})
4
+ @layout = klass.new
5
+ @layout.scrollDirection = map_layout_direction(options.fetch(:direction, :vertical))
6
+
7
+ @layout.minimumLineSpacing = options[:minimum_line_spacing] if options.has_key?(:minimum_line_spacing)
8
+ @layout.minimumInteritemSpacing = options[:minimum_interitem_spacing] if options.has_key?(:minimum_interitem_spacing)
9
+ @layout.itemSize = options[:item_size] if options.has_key?(:item_size)
10
+ @layout.estimatedItemSize = options[:estimated_item_size] if options.has_key?(:estimated_item_size) and @layout.respond_to?(:estimatedItemSize)
11
+ @layout.sectionInset = options[:section_inset] if options.has_key?(:section_inset)
12
+ @layout
13
+ end
14
+
15
+ def get_collection_layout
16
+ @layout ||= begin
17
+ layout = UICollectionViewFlowLayout.new
18
+ layout.scrollDirection = UICollectionViewScrollDirectionHorizontal
19
+
20
+ layout
21
+ end
22
+ end
23
+
24
+ def map_layout_direction(symbol)
25
+ {
26
+ horizontal: UICollectionViewScrollDirectionHorizontal,
27
+ vertical: UICollectionViewScrollDirectionVertical
28
+ }[symbol] || symbol || UICollectionViewScrollDirectionVertical
29
+ end
30
+
31
+ def cell_classes(options={})
32
+ @cell_classes = options
33
+ end
34
+
35
+ def get_cell_classes
36
+ @cell_classes || nil
37
+ end
38
+ end