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 +4 -4
- data/README.md +12 -7
- data/lib/ProMotion/screen/nav_bar_module.rb +6 -2
- data/lib/ProMotion/screen/screen_module.rb +38 -0
- data/lib/ProMotion/styling/styling.rb +3 -1
- data/lib/ProMotion/table/cell/table_view_cell_module.rb +1 -1
- data/lib/ProMotion/table/data/table_data.rb +4 -0
- data/lib/ProMotion/table/extensions/longpressable.rb +1 -0
- data/lib/ProMotion/table/extensions/refreshable.rb +3 -0
- data/lib/ProMotion/table/table.rb +95 -16
- data/lib/ProMotion/version.rb +1 -1
- data/spec/functional/func_table_screen_cell_spec.rb +44 -0
- data/spec/functional/func_table_screen_spec.rb +2 -2
- data/spec/unit/screen_spec.rb +42 -0
- data/spec/unit/tables/table_module_spec.rb +4 -0
- data/spec/unit/tables/table_screen_spec.rb +110 -0
- data/spec/unit/view_helper_spec.rb +25 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37daeda0dc99301ea7bb1fd7ab847e3fd1803cb1
|
4
|
+
data.tar.gz: 420f59061a730bb933e13a3fa0737be210be85de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
94
|
-
|
95
|
-
This release includes
|
96
|
-
|
97
|
-
*
|
98
|
-
*
|
99
|
-
*
|
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
|
-
|
39
|
-
|
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
|
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
|
|
@@ -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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|
data/lib/ProMotion/version.rb
CHANGED
@@ -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", :
|
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", :
|
92
|
+
flick("A non-deletable blank row", to: :left)
|
93
93
|
|
94
94
|
wait 0.11 do
|
95
95
|
# Tap the delete button
|
data/spec/unit/screen_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|