ProMotion 2.1.0 → 2.2.0

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