ProMotion 2.1.0 → 2.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4ec0cb821081f967b54a5a719cb0144e97d4921
4
- data.tar.gz: 42f01567d81eac734b854fb8f2d749207a755cb0
3
+ metadata.gz: 37daeda0dc99301ea7bb1fd7ab847e3fd1803cb1
4
+ data.tar.gz: 420f59061a730bb933e13a3fa0737be210be85de
5
5
  SHA512:
6
- metadata.gz: 042c8b42abce3767dfd6dc18e759391f2edc6018d56ef3438a99dc9d131dd5359a164cf0a693d07246d6b4b31aa7146940e757a29fdc290e8e98d4046206a7f6
7
- data.tar.gz: 063f34003549f6d15c8782cd99b8ea921ce8d3ba80b6bc692f1f7e9e5ac294a792cc959c63654c6ef1988b50d1b8757a290259848770d56abf514de5a576efbd
6
+ metadata.gz: 615447c2fffa5b940a792db69c5cac17d37f9b617323e5cc64cbdbf40f1007b8aff1bd8650e66d67400049e8cfb5f76a3d3543376c62cdd930c596e07aa126f4
7
+ data.tar.gz: 0275defb4b361f3ea70d3bb6f69ba5a78017dc271a40125f796083ee83cd57d3a63d4bcdefaab165b57c8790ad15a8f536bc3a150ccffb3d3cac77bc151b6c41
data/README.md CHANGED
@@ -90,13 +90,18 @@ end
90
90
 
91
91
  # Changelog
92
92
 
93
- ## Version 2.1.0
94
-
95
- This release includes a few minor new features, but mainly it's a bugfix release and upgrading should go smoothly.
96
-
97
- * Added `hide_nav_bar` option to screen init args
98
- * `update_table_data` can now take `index_paths:` array to selectively update cells
99
- * Table cell `style` has been changed to `properties`. `style` will persist as an alias for backwards-compatibility
93
+ ## Version 2.2.0
94
+
95
+ This release includes several new features and is backwards compatible with all 2.x releases.
96
+
97
+ * PM::TableScreen: You can now set a custom table view header view ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/556))
98
+ * PM::TableScreen refreshable: Refresh controls now show when programmatically initiating refresh ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/569))
99
+ * PM::TableScreen: Added reorderable ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/569))
100
+ * PM::TableScreen: Added auto height feature ([thanks Carlin Isaacson](https://github.com/clearsightstudio/ProMotion/pull/574))
101
+ * PM::Screen: The navigation controller bottom toolbar will auto-hide when passed nil or false ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/577))
102
+ * PM::Screen: You can now choose a status bar style ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/563))
103
+ * Added `on_load` and `on_styled` hooks for UIViews that implement those methods ([Jamon Holmgren](https://github.com/clearsightstudio/ProMotion/pull/567))
104
+ * Fixed an issue where cell properties would be applied twice unnecessarily ([Jamon Holmgren](https://github.com/clearsightstudio/ProMotion/pull/573))
100
105
 
101
106
  # API Reference
102
107
 
@@ -35,8 +35,12 @@ module ProMotion
35
35
  alias_method :set_nav_bar_right_button, :set_nav_bar_left_button
36
36
 
37
37
  def set_toolbar_items(buttons = [], animated = true)
38
- self.toolbarItems = Array(buttons).map{|b| b.is_a?(UIBarButtonItem) ? b : create_toolbar_button(b) }
39
- navigationController.setToolbarHidden(false, animated:animated)
38
+ if buttons
39
+ self.toolbarItems = Array(buttons).map{|b| b.is_a?(UIBarButtonItem) ? b : create_toolbar_button(b) }
40
+ navigationController.setToolbarHidden(false, animated:animated)
41
+ else
42
+ navigationController.setToolbarHidden(true, animated:animated)
43
+ end
40
44
  end
41
45
  alias_method :set_toolbar_buttons, :set_toolbar_items
42
46
  alias_method :set_toolbar_button, :set_toolbar_items
@@ -33,6 +33,27 @@ module ProMotion
33
33
  end
34
34
  end
35
35
 
36
+ def resolve_status_bar
37
+ case self.class.status_bar_type
38
+ when :none
39
+ status_bar_hidden true
40
+ when :light
41
+ status_bar_hidden false
42
+ status_bar_style UIStatusBarStyleLightContent
43
+ else
44
+ status_bar_hidden false
45
+ status_bar_style UIStatusBarStyleDefault
46
+ end
47
+ end
48
+
49
+ def status_bar_hidden(hidden)
50
+ UIApplication.sharedApplication.setStatusBarHidden(hidden, withAnimation:self.class.status_bar_animation)
51
+ end
52
+
53
+ def status_bar_style(style)
54
+ UIApplication.sharedApplication.setStatusBarStyle(style)
55
+ end
56
+
36
57
  def parent_screen=(parent)
37
58
  @parent_screen = WeakRef.new(parent)
38
59
  end
@@ -46,6 +67,7 @@ module ProMotion
46
67
  end
47
68
 
48
69
  def view_will_appear(animated)
70
+ resolve_status_bar
49
71
  self.will_appear
50
72
 
51
73
  self.will_present if isMovingToParentViewController
@@ -191,6 +213,22 @@ module ProMotion
191
213
  @title = t
192
214
  @title_type = :view
193
215
  end
216
+
217
+ def status_bar(style=nil, args={})
218
+ if NSBundle.mainBundle.objectForInfoDictionaryKey('UIViewControllerBasedStatusBarAppearance').nil?
219
+ PM.logger.warn("status_bar will have no effect unless you set 'UIViewControllerBasedStatusBarAppearance' to false in your info.plist")
220
+ end
221
+ @status_bar_style = style
222
+ @status_bar_animation = args[:animation] if args[:animation]
223
+ end
224
+
225
+ def status_bar_type
226
+ @status_bar_style || :default
227
+ end
228
+
229
+ def status_bar_animation
230
+ @status_bar_animation || UIStatusBarAnimationSlide
231
+ end
194
232
  end
195
233
 
196
234
  def self.included(base)
@@ -3,11 +3,12 @@ module ProMotion
3
3
  def set_attributes(element, args = {})
4
4
  args = get_attributes_from_symbol(args)
5
5
  args.each { |k, v| set_attribute(element, k, v) }
6
+ element.send(:on_styled) if element.respond_to?(:on_styled)
6
7
  element
7
8
  end
8
9
 
9
10
  def set_attribute(element, k, v)
10
- return element unless element
11
+ return unless element
11
12
 
12
13
  if !element.is_a?(CALayer) && v.is_a?(Hash) && element.respond_to?("#{k}=")
13
14
  element.send("#{k}=", v)
@@ -71,6 +72,7 @@ module ProMotion
71
72
  Array(elements).each do |element|
72
73
  parent_element.addSubview element
73
74
  set_attributes(element, attrs) if attrs && attrs.length > 0
75
+ element.send(:on_load) if element.respond_to?(:on_load)
74
76
  end
75
77
  elements
76
78
  end
@@ -23,7 +23,7 @@ module ProMotion
23
23
 
24
24
  # TODO: Remove this in ProMotion 2.1. Just for migration purposes.
25
25
  def check_deprecated_styles
26
- whitelist = [ :title, :subtitle, :image, :remote_image, :accessory, :selection_style, :action, :long_press_action, :arguments, :cell_style, :cell_class, :cell_identifier, :editing_style, :search_text, :keep_selection, :height, :accessory_type, :style, :properties ]
26
+ whitelist = [ :title, :subtitle, :image, :remote_image, :accessory, :selection_style, :action, :long_press_action, :arguments, :cell_style, :cell_class, :cell_identifier, :editing_style, :moveable, :search_text, :keep_selection, :height, :accessory_type, :style, :properties ]
27
27
  if (data_cell.keys - whitelist).length > 0
28
28
  PM.logger.deprecated("In #{self.table_screen.class.to_s}#table_data, you should set :#{(data_cell.keys - whitelist).join(", :")} in a `properties:` hash. See TableScreen documentation.")
29
29
  end
@@ -35,6 +35,10 @@ module ProMotion
35
35
  table_section[:cells].delete_at(params[:index].to_i)
36
36
  end
37
37
 
38
+ def move_cell(from, to)
39
+ section(to.section)[:cells].insert(to.row, section(from.section)[:cells].delete_at(from.row))
40
+ end
41
+
38
42
  def search(search_string)
39
43
  start_searching(search_string)
40
44
 
@@ -1,6 +1,7 @@
1
1
  module ProMotion
2
2
  module Table
3
3
  module Longpressable
4
+
4
5
  def make_longpressable(params={})
5
6
  params = {
6
7
  min_duration: 1.0
@@ -19,6 +19,9 @@ module ProMotion
19
19
  return unless @refresh_control
20
20
 
21
21
  @refresh_control.beginRefreshing
22
+
23
+ # Scrolls the table down to show the refresh control when invoked programatically
24
+ table_view.setContentOffset(CGPointMake(0, table_view.contentOffset.y-@refresh_control.frame.size.height), animated:true) if table_view.contentOffset.y > -65.0
22
25
  end
23
26
  alias :begin_refreshing :start_refreshing
24
27
 
@@ -15,9 +15,11 @@ module ProMotion
15
15
 
16
16
  def screen_setup
17
17
  check_table_data
18
+ set_up_header_view
18
19
  set_up_searchable
19
20
  set_up_refreshable
20
21
  set_up_longpressable
22
+ set_up_row_height
21
23
  end
22
24
 
23
25
  def check_table_data
@@ -28,6 +30,17 @@ module ProMotion
28
30
  @promotion_table_data ||= TableData.new(table_data, table_view)
29
31
  end
30
32
 
33
+ def set_up_header_view
34
+ if self.respond_to?(:table_header_view)
35
+ header_view = self.table_header_view
36
+ if header_view.is_a? UIView
37
+ self.tableView.tableHeaderView = header_view
38
+ else
39
+ PM.logger.warn "Table header views must be a UIView."
40
+ end
41
+ end
42
+ end
43
+
31
44
  def set_up_searchable
32
45
  if self.class.respond_to?(:get_searchable) && self.class.get_searchable
33
46
  self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params)
@@ -50,6 +63,13 @@ module ProMotion
50
63
  end
51
64
  end
52
65
 
66
+ def set_up_row_height
67
+ if self.class.respond_to?(:get_row_height) && params = self.class.get_row_height
68
+ self.view.rowHeight = params[:height]
69
+ self.view.estimatedRowHeight = params[:estimated]
70
+ end
71
+ end
72
+
53
73
  def searching?
54
74
  self.promotion_table_data.filtered
55
75
  end
@@ -78,7 +98,6 @@ module ProMotion
78
98
 
79
99
  def trigger_action(action, arguments, index_path)
80
100
  return PM.logger.info "Action not implemented: #{action.to_s}" unless self.respond_to?(action)
81
-
82
101
  case self.method(action).arity
83
102
  when 0 then self.send(action) # Just call the method
84
103
  when 2 then self.send(action, arguments, index_path) # Send arguments and index path
@@ -111,22 +130,17 @@ module ProMotion
111
130
  table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation: map_row_animation_symbol(animation)) if deletable_index_paths.length > 0
112
131
  end
113
132
 
114
- def table_view_cell(params={})
115
- params = index_path_to_section_index(params)
116
- data_cell = self.promotion_table_data.cell(section: params[:section], index: params[:index])
117
- return UITableViewCell.alloc.init unless data_cell
118
- create_table_cell(data_cell)
119
- end
120
-
121
133
  def create_table_cell(data_cell)
134
+ new_cell = nil
122
135
  table_cell = table_view.dequeueReusableCellWithIdentifier(data_cell[:cell_identifier]) || begin
123
- table_cell = data_cell[:cell_class].alloc.initWithStyle(data_cell[:cell_style], reuseIdentifier:data_cell[:cell_identifier])
124
- table_cell.extend(PM::TableViewCellModule) unless table_cell.is_a?(PM::TableViewCellModule)
125
- table_cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
126
- table_cell.clipsToBounds = true # fix for changed default in 7.1
127
- table_cell
136
+ new_cell = data_cell[:cell_class].alloc.initWithStyle(data_cell[:cell_style], reuseIdentifier:data_cell[:cell_identifier])
137
+ new_cell.extend(PM::TableViewCellModule) unless new_cell.is_a?(PM::TableViewCellModule)
138
+ new_cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
139
+ new_cell.clipsToBounds = true # fix for changed default in 7.1
140
+ new_cell.setup(data_cell, self)
141
+ new_cell
128
142
  end
129
- table_cell.setup(data_cell, self)
143
+ table_cell.send(:on_reuse) if !new_cell && table_cell.respond_to?(:on_reuse)
130
144
  table_cell
131
145
  end
132
146
 
@@ -138,6 +152,21 @@ module ProMotion
138
152
  self.promotion_table_data.search(search_string) if searching?
139
153
  end
140
154
 
155
+ def toggle_edit_mode(animated = true)
156
+ edit_mode({enabled: !editing?, animated: animated})
157
+ end
158
+
159
+ def edit_mode(args = {})
160
+ args[:enabled] = false if args[:enabled].nil?
161
+ args[:animated] = true if args[:animated].nil?
162
+
163
+ setEditing(args[:enabled], animated:args[:animated])
164
+ end
165
+
166
+ def edit_mode?
167
+ !!isEditing
168
+ end
169
+
141
170
  ########## Cocoa touch methods #################
142
171
  def numberOfSectionsInTableView(table_view)
143
172
  self.promotion_table_data.sections.length
@@ -161,12 +190,15 @@ module ProMotion
161
190
  end
162
191
 
163
192
  def tableView(table_view, cellForRowAtIndexPath: index_path)
164
- table_view_cell(index_path: index_path)
193
+ params = index_path_to_section_index(index_path: index_path)
194
+ data_cell = self.promotion_table_data.cell(section: params[:section], index: params[:index])
195
+ return UITableViewCell.alloc.init unless data_cell
196
+ create_table_cell(data_cell)
165
197
  end
166
198
 
167
199
  def tableView(table_view, willDisplayCell: table_cell, forRowAtIndexPath: index_path)
168
200
  data_cell = self.promotion_table_data.cell(index_path: index_path)
169
- set_attributes table_cell, data_cell[:properties] if data_cell[:properties]
201
+ table_cell.setup(data_cell, self) if table_cell.respond_to?(:setup)
170
202
  table_cell.send(:will_display) if table_cell.respond_to?(:will_display)
171
203
  table_cell.send(:restyle!) if table_cell.respond_to?(:restyle!) # Teacup compatibility
172
204
  end
@@ -192,6 +224,43 @@ module ProMotion
192
224
  end
193
225
  end
194
226
 
227
+ def tableView(tableView, canMoveRowAtIndexPath:index_path)
228
+ data_cell = self.promotion_table_data.cell(index_path: index_path, unfiltered: true)
229
+
230
+ if (!data_cell[:moveable].nil? || data_cell[:moveable].is_a?(Symbol)) && data_cell[:moveable] != false
231
+ true
232
+ else
233
+ false
234
+ end
235
+ end
236
+
237
+ def tableView(tableView, targetIndexPathForMoveFromRowAtIndexPath:source_index_path, toProposedIndexPath:proposed_destination_index_path)
238
+ data_cell = self.promotion_table_data.cell(index_path: source_index_path, unfiltered: true)
239
+
240
+ if data_cell[:moveable] == :section && source_index_path.section != proposed_destination_index_path.section
241
+ source_index_path
242
+ else
243
+ proposed_destination_index_path
244
+ end
245
+ end
246
+
247
+ def tableView(tableView, moveRowAtIndexPath:from_index_path, toIndexPath:to_index_path)
248
+ self.promotion_table_data.move_cell(from_index_path, to_index_path)
249
+
250
+ if self.respond_to?("on_cell_moved:")
251
+ args = {
252
+ paths: {
253
+ from: from_index_path,
254
+ to: to_index_path
255
+ },
256
+ cell: self.promotion_table_data.section(to_index_path.section)[:cells][to_index_path.row]
257
+ }
258
+ send(:on_cell_moved, args)
259
+ else
260
+ PM.logger.warn "Implement the on_cell_moved method in your PM::TableScreen to be notified when a user moves a cell."
261
+ end
262
+ end
263
+
195
264
  def tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index)
196
265
  return index unless ["{search}", UITableViewIndexSearch].include?(self.table_data_index[0])
197
266
 
@@ -255,6 +324,16 @@ module ProMotion
255
324
  UITableViewStylePlain
256
325
  end
257
326
 
327
+ def row_height(height, args={})
328
+ height = UITableViewAutomaticDimension if height == :auto
329
+ args[:estimated] ||= height unless height == UITableViewAutomaticDimension
330
+ @row_height = { height: height, estimated: args[:estimated] || 44.0 }
331
+ end
332
+
333
+ def get_row_height
334
+ @row_height ||= nil
335
+ end
336
+
258
337
  # Searchable
259
338
  def searchable(params={})
260
339
  @searchable_params = params
@@ -1,3 +1,3 @@
1
1
  module ProMotion
2
- VERSION = "2.1.0" unless defined?(ProMotion::VERSION)
2
+ VERSION = "2.2.0" unless defined?(ProMotion::VERSION)
3
3
  end
@@ -0,0 +1,44 @@
1
+ describe "ProMotion::TableScreen functionality" do
2
+ tests PM::TestMiniTableScreen
3
+
4
+ def table_screen
5
+ @table_screen ||= begin
6
+ t = TestMiniTableScreen.new(nav_bar: true)
7
+ t
8
+ end
9
+ end
10
+
11
+ def controller
12
+ table_screen.navigationController
13
+ end
14
+
15
+ before do
16
+ UIView.setAnimationsEnabled false
17
+ end
18
+
19
+ after do
20
+ @table_screen = nil
21
+ end
22
+
23
+ it "no cells have fired on_reuse before scrolling" do
24
+ ip = NSIndexPath.indexPathForRow(0, inSection: 0)
25
+ cell = table_screen.tableView(table_screen.table_view, cellForRowAtIndexPath: ip)
26
+ cell.on_reuse_fired.should.not == true
27
+ end
28
+
29
+ it "cell has fired on_reuse after scrolling" do
30
+ ip = NSIndexPath.indexPathForRow(10, inSection: 0)
31
+ table_screen.tableView.scrollToRowAtIndexPath(ip, atScrollPosition: UITableViewScrollPositionTop, animated: false)
32
+ wait 0.001 do
33
+ ip = NSIndexPath.indexPathForRow(0, inSection: 0)
34
+ table_screen.tableView.scrollToRowAtIndexPath(ip, atScrollPosition: UITableViewScrollPositionTop, animated: false)
35
+
36
+ cell = views(TestCell).first
37
+ cell.on_reuse_fired.should == true
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+
44
+
@@ -70,7 +70,7 @@ describe "ProMotion::TableScreen functionality" do
70
70
  it "should use editing_style to delete the table row" do
71
71
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
72
72
  table_screen.cell_was_deleted.should != true
73
- flick("Just another deletable blank row", :to => :left)
73
+ flick("Just another deletable blank row", to: :left)
74
74
 
75
75
  wait 0.11 do
76
76
  # Tap the delete button
@@ -89,7 +89,7 @@ describe "ProMotion::TableScreen functionality" do
89
89
  it "should not allow deleting if on_cell_delete returns `false`" do
90
90
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
91
91
  table_screen.cell_was_deleted.should != true
92
- flick("A non-deletable blank row", :to => :left)
92
+ flick("A non-deletable blank row", to: :left)
93
93
 
94
94
  wait 0.11 do
95
95
  # Tap the delete button
@@ -26,6 +26,25 @@ describe "screen properties" do
26
26
  HomeScreen.title.should != 'instance method'
27
27
  end
28
28
 
29
+ it "should have a default UIStatusBar style" do
30
+ @screen.view_will_appear(false)
31
+ UIApplication.sharedApplication.isStatusBarHidden.should == false
32
+ UIApplication.sharedApplication.statusBarStyle.should == UIStatusBarStyleDefault
33
+ end
34
+
35
+ it "should set the UIStatusBar style to :none" do
36
+ @screen.class.status_bar :none
37
+ @screen.view_will_appear(false)
38
+ UIApplication.sharedApplication.isStatusBarHidden.should == true
39
+ end
40
+
41
+ it "should set the UIStatusBar style to :light" do
42
+ @screen.class.status_bar :light
43
+ @screen.view_will_appear(false)
44
+ UIApplication.sharedApplication.isStatusBarHidden.should == false
45
+ UIApplication.sharedApplication.statusBarStyle.should == UIStatusBarStyleLightContent
46
+ end
47
+
29
48
  it "should set the tab bar item with a system item" do
30
49
  @screen.set_tab_bar_item system_item: :contacts
31
50
  comparison = UITabBarItem.alloc.initWithTabBarSystemItem(UITabBarSystemItemContacts, tag: 0)
@@ -267,6 +286,29 @@ describe "screen with toolbar" do
267
286
  screen.navigationController.toolbarHidden?.should == false
268
287
  end
269
288
 
289
+ it "doesn't show the toolbar when passed nil" do
290
+ screen = HomeScreen.new modal: true, nav_bar: true, toolbar: true
291
+ screen.on_load
292
+ screen.set_toolbar_button(nil, false)
293
+ screen.navigationController.toolbarHidden?.should == true
294
+ end
295
+
296
+ it "doesn't show the toolbar when passed false" do
297
+ screen = HomeScreen.new modal: true, nav_bar: true, toolbar: true
298
+ screen.on_load
299
+ screen.set_toolbar_button(false, false)
300
+ screen.navigationController.toolbarHidden?.should == true
301
+ end
302
+
303
+ it "hides the toolbar when passed nil" do
304
+ screen = HomeScreen.new modal: true, nav_bar: true, toolbar: true
305
+ screen.on_load
306
+ screen.set_toolbar_button([{title: "Testing Toolbar"}], false)
307
+ screen.navigationController.toolbarHidden?.should == false
308
+ screen.set_toolbar_button(nil, false)
309
+ screen.navigationController.toolbarHidden?.should == true
310
+ end
311
+
270
312
  end
271
313
 
272
314
  describe 'toolbar tinted buttons' do
@@ -172,6 +172,10 @@ describe "PM::Table module" do
172
172
  cell.backgroundColor.should == UIColor.blueColor
173
173
  end
174
174
 
175
+ it "should have a header view" do
176
+ @subject.tableView.tableHeaderView.class.should == UIImageView
177
+ end
178
+
175
179
  describe("section with custom title_view") do
176
180
 
177
181
  it "should use the correct class for section view" do
@@ -50,6 +50,18 @@ describe "table screens" do
50
50
  end
51
51
  end
52
52
 
53
+ it "sets the auto row height and estimated row height properly" do
54
+ @screen.view.rowHeight.should == UITableViewAutomaticDimension
55
+ @screen.view.estimatedRowHeight.should == 97
56
+ end
57
+
58
+ it "sets the fixed row height properly" do
59
+ screen = UpdateTestTableScreen.new
60
+
61
+ screen.view.rowHeight.should == 77
62
+ screen.view.estimatedRowHeight.should == 77
63
+ end
64
+
53
65
  end
54
66
 
55
67
  describe "search functionality" do
@@ -126,5 +138,103 @@ describe "table screens" do
126
138
 
127
139
  end
128
140
 
141
+ describe "test PM::TableScreen's moving cells functionality" do
142
+ before do
143
+ UIView.animationsEnabled = false
144
+ @screen = TestTableScreen.new
145
+ @screen.on_load
146
+ end
147
+
148
+ it "should allow the table screen to enter editing mode" do
149
+ @screen.isEditing.should == false
150
+ @screen.edit_mode(enabled:true, animated:false)
151
+ @screen.isEditing.should == true
152
+ end
153
+
154
+ it "should use a convenience method to see if the table is editing" do
155
+ @screen.isEditing.should == @screen.edit_mode?
156
+ @screen.edit_mode(enabled:true, animated:false)
157
+ @screen.isEditing.should == @screen.edit_mode?
158
+ end
159
+
160
+ it "should toggle editing mode" do
161
+ @screen.edit_mode?.should == false
162
+ @screen.toggle_edit_mode(false)
163
+ @screen.edit_mode?.should == true
164
+ @screen.toggle_edit_mode(false)
165
+ @screen.edit_mode?.should == false
166
+ end
167
+
168
+ it "should return true for cells that are moveable" do
169
+ # Index path with :moveable = true
170
+ index_path = NSIndexPath.indexPathForRow(0, inSection:4)
171
+ @screen.tableView(@screen.tableView, canMoveRowAtIndexPath: index_path).should == true
172
+
173
+ # Index path with no :moveable set
174
+ index_path = NSIndexPath.indexPathForRow(2, inSection:4)
175
+ @screen.tableView(@screen.tableView, canMoveRowAtIndexPath: index_path).should == false
176
+
177
+ # Index path with :moveable = false
178
+ index_path = NSIndexPath.indexPathForRow(4, inSection:4)
179
+ @screen.tableView(@screen.tableView, canMoveRowAtIndexPath: index_path).should == false
180
+ end
181
+
182
+ it "should rearrange the data object when a cell is moved" do
183
+ move_from = NSIndexPath.indexPathForRow(0, inSection:4)
184
+ move_to = NSIndexPath.indexPathForRow(2, inSection:4)
185
+
186
+ @screen.promotion_table_data.section(4)[:cells].map{|c| c[:title]}.should == [
187
+ 'Cell 1',
188
+ 'Cell 2',
189
+ 'Cell 3',
190
+ 'Cell 4',
191
+ 'Cell 5'
192
+ ]
193
+ @screen.tableView(@screen.tableView, moveRowAtIndexPath:move_from, toIndexPath:move_to)
194
+ @screen.promotion_table_data.section(4)[:cells].map{|c| c[:title]}.should == [
195
+ 'Cell 2',
196
+ 'Cell 3',
197
+ 'Cell 1',
198
+ 'Cell 4',
199
+ 'Cell 5'
200
+ ]
201
+ end
202
+
203
+ it "should call :cell_moved when moving a cell" do
204
+ move_from = NSIndexPath.indexPathForRow(0, inSection:4)
205
+ move_to = NSIndexPath.indexPathForRow(2, inSection:4)
206
+
207
+ @screen.cell_was_moved.nil?.should == true
208
+ @screen.tableView(@screen.tableView, moveRowAtIndexPath:move_from, toIndexPath:move_to)
209
+ @screen.cell_was_moved.is_a?(Hash).should == true
210
+
211
+ cell = @screen.cell_was_moved
212
+
213
+ cell[:paths][:from].should == move_from
214
+ cell[:paths][:to].should == move_to
215
+
216
+ cell[:cell][:title].should == "Cell 1"
217
+ end
218
+
219
+ it "should allow cells to move to other sections" do
220
+ move_from = NSIndexPath.indexPathForRow(1, inSection:4)
221
+ move_to = NSIndexPath.indexPathForRow(0, inSection:3)
222
+
223
+ moving_to = @screen.tableView(@screen.tableView, targetIndexPathForMoveFromRowAtIndexPath:move_from, toProposedIndexPath:move_to)
224
+
225
+ moving_to.should == move_to
226
+ end
227
+
228
+ it "should not allow cells to move to other sections" do
229
+ move_from = NSIndexPath.indexPathForRow(0, inSection:4)
230
+ move_to = NSIndexPath.indexPathForRow(0, inSection:3)
231
+
232
+ moving_to = @screen.tableView(@screen.tableView, targetIndexPathForMoveFromRowAtIndexPath:move_from, toProposedIndexPath:move_to)
233
+
234
+ moving_to.should == move_from
235
+ end
236
+
237
+ end
238
+
129
239
  end
130
240
 
@@ -1,3 +1,16 @@
1
+ class TestView < UIView
2
+ attr_accessor :on_load_fired
3
+ attr_accessor :on_styled_fired
4
+
5
+ def on_load
6
+ self.on_load_fired = true
7
+ end
8
+
9
+ def on_styled
10
+ self.on_styled_fired = true
11
+ end
12
+ end
13
+
1
14
  describe "view helpers" do
2
15
 
3
16
  def equal_rect(rect)
@@ -61,6 +74,18 @@ describe "view helpers" do
61
74
  layered_view.layer.backgroundColor.should == UIColor.redColor.CGColor
62
75
  end
63
76
 
77
+ it "should trigger on_load on a view that supports it" do
78
+ v = TestView.new
79
+ @dummy.add v
80
+ v.on_load_fired.should == true
81
+ end
82
+
83
+ it "should trigger on_styled on a view that supports it" do
84
+ v = TestView.new
85
+ @dummy.set_attributes v, { background_color: UIColor.blueColor }
86
+ v.on_styled_fired.should == true
87
+ end
88
+
64
89
 
65
90
  context "content sizing" do
66
91
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ProMotion
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamon Holmgren
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-11-18 00:00:00.000000000 Z
13
+ date: 2014-12-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: methadone
@@ -133,6 +133,7 @@ files:
133
133
  - lib/ProMotion/web/web_screen_module.rb
134
134
  - spec/functional/func_screen_spec.rb
135
135
  - spec/functional/func_split_screen_spec.rb
136
+ - spec/functional/func_table_screen_cell_spec.rb
136
137
  - spec/functional/func_table_screen_spec.rb
137
138
  - spec/functional/func_table_screen_updating_spec.rb
138
139
  - spec/functional/func_web_screen_spec.rb
@@ -191,6 +192,7 @@ summary: ProMotion is a fast way to get started building RubyMotion apps. Instea
191
192
  test_files:
192
193
  - spec/functional/func_screen_spec.rb
193
194
  - spec/functional/func_split_screen_spec.rb
195
+ - spec/functional/func_table_screen_cell_spec.rb
194
196
  - spec/functional/func_table_screen_spec.rb
195
197
  - spec/functional/func_table_screen_updating_spec.rb
196
198
  - spec/functional/func_web_screen_spec.rb