ProMotion 2.0.1 → 2.1.0.beta1

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: 26a3f842a22164f1646fa4c70c06717331c37b37
4
- data.tar.gz: b71313bd4e58fd83a405e8741c264547b80e0f19
3
+ metadata.gz: 069e30500b3574a7ff83d4a179af392513ffac2b
4
+ data.tar.gz: e7a65eb50f555d29c2b406deaf3f4bb0c9e88aa1
5
5
  SHA512:
6
- metadata.gz: 309c74e1577110e7c0ab397fe120a367f77343b11f5cfb4813bd99e6f942f89d463eadc36fc143324c49b7fd428ba50191c896246a91dddb17f6d05048eac843
7
- data.tar.gz: c0dbd687ecb04bdea39a131e9b8313da6b12ca5b3a83fc7ab8a6ee915b4efc8ead92fb10247c16613907167f83c877c441078b2da22408003ef5f0212f91ce62
6
+ metadata.gz: 24902da29b4aef04a2620dd41a527052c39a3d9e5bcba5f556d3048cf83a7558b58c8b72ed28ae54f04c92dfb8b6bee847ce842b85c5f2ac6f574ddb70bb3dab
7
+ data.tar.gz: 007f7044aa819c3ce5e1a9b4e16048886984bc65aaf8d8fd16757a43a481ef52753919a9e6d9eaa62ef54cbb217ab73865ed71c601167de11a744d2a8ef20e7c
data/README.md CHANGED
@@ -1,4 +1,10 @@
1
- # ProMotion [![Gem Version](https://badge.fury.io/rb/ProMotion.png)](http://badge.fury.io/rb/ProMotion) [![Build Status](https://travis-ci.org/clearsightstudio/ProMotion.png)](https://travis-ci.org/clearsightstudio/ProMotion) [![Code Climate](https://codeclimate.com/github/clearsightstudio/ProMotion.png)](https://codeclimate.com/github/clearsightstudio/ProMotion) [![Dependency Status](https://gemnasium.com/clearsightstudio/ProMotion.png)](https://gemnasium.com/clearsightstudio/ProMotion)
1
+ # ProMotion
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/ProMotion.png)](http://badge.fury.io/rb/ProMotion)
4
+ [![Build Status](https://travis-ci.org/clearsightstudio/ProMotion.png)](https://travis-ci.org/clearsightstudio/ProMotion)
5
+ [![Code Climate](https://codeclimate.com/github/clearsightstudio/ProMotion.png)](https://codeclimate.com/github/clearsightstudio/ProMotion)
6
+ [![Dependency Status](https://gemnasium.com/clearsightstudio/ProMotion.png)](https://gemnasium.com/clearsightstudio/ProMotion)
7
+ [![omniref](https://www.omniref.com/ruby/gems/ProMotion.png)](https://www.omniref.com/ruby/gems/ProMotion)
2
8
 
3
9
  ## iPhone Apps, Ruby-style
4
10
 
data/lib/ProMotion.rb CHANGED
@@ -9,4 +9,24 @@ Motion::Project::App.setup do |app|
9
9
  Dir.glob(File.join(core_lib, '**/*.rb')).reverse.each do |file|
10
10
  app.files.insert(insert_point, file)
11
11
  end
12
+
13
+ # For compatibility with libraries that don't use detect_dependencies. :-(
14
+ app.files_dependencies({
15
+ "#{core_lib}/cocoatouch/table_view_cell.rb" => [ "#{core_lib}/table/cell/table_view_cell_module.rb" ],
16
+ "#{core_lib}/table/cell/table_view_cell_module.rb" => [ "#{core_lib}/styling/styling.rb" ],
17
+ "#{core_lib}/delegate/delegate.rb" => [ "#{core_lib}/delegate/delegate_parent.rb" ],
18
+ "#{core_lib}/delegate/delegate_parent.rb" => [ "#{core_lib}/delegate/delegate_module.rb" ],
19
+ "#{core_lib}/delegate/delegate_module.rb" => [ "#{core_lib}/tabs/tabs.rb", "#{core_lib}/ipad/split_screen.rb" ],
20
+ "#{core_lib}/screen/screen.rb" => [ "#{core_lib}/screen/screen_module.rb" ],
21
+ "#{core_lib}/screen/screen_module.rb" => [ "#{core_lib}/screen/screen_navigation.rb" ],
22
+ "#{core_lib}/table/data/table_data.rb" => [ "#{core_lib}/table/table.rb" ],
23
+ "#{core_lib}/table/table.rb" => [
24
+ "#{core_lib}/table/table_utils.rb",
25
+ "#{core_lib}/table/extensions/searchable.rb",
26
+ "#{core_lib}/table/extensions/refreshable.rb",
27
+ "#{core_lib}/table/extensions/indexable.rb",
28
+ "#{core_lib}/table/extensions/longpressable.rb"
29
+ ],
30
+ "#{core_lib}/web/web_screen.rb" => [ "#{core_lib}/web/web_screen_module.rb" ],
31
+ })
12
32
  end
@@ -2,10 +2,8 @@ module ProMotion
2
2
  class NavigationController < UINavigationController
3
3
 
4
4
  def popViewControllerAnimated(animated)
5
- if self.viewControllers[-2].respond_to? :on_back
6
- self.viewControllers[-2].send(:on_back)
7
- end
8
- super animated
5
+ super
6
+ self.viewControllers.last.send(:on_back) if self.viewControllers.last.respond_to?(:on_back)
9
7
  end
10
8
 
11
9
  def shouldAutorotate
@@ -19,12 +19,17 @@ module ProMotion
19
19
  error: [:error],
20
20
  warn: [:error, :warn],
21
21
  info: [:error, :warn, :info],
22
+ debug: [:error, :warn, :info, :debug],
22
23
  verbose: [:error, :warn, :info, :debug, :verbose],
23
- debug: [:error, :warn, :info, :debug, :verbose]
24
24
  }
25
25
 
26
26
  def level
27
- @level ||= :debug
27
+ @level ||= (RUBYMOTION_ENV == "release" ? :error : :debug)
28
+ end
29
+
30
+ def level=(new_level)
31
+ log('LOG LEVEL', 'Setting PM.logger to :verbose will make everything REALLY SLOW!', :purple) if new_level == :verbose
32
+ @level = new_level
28
33
  end
29
34
 
30
35
  def levels
@@ -33,9 +38,9 @@ module ProMotion
33
38
 
34
39
  # Usage: PM.logger.log("ERROR", "message here", :red)
35
40
  def log(label, message_text, color)
36
- return if defined?(RUBYMOTION_ENV) && RUBYMOTION_ENV == "test"
41
+ # return if defined?(RUBYMOTION_ENV) && RUBYMOTION_ENV == "test"
37
42
  color = COLORS[color] || COLORS[:default]
38
- puts color[0] + NAME + "[#{label}] #{message_text}" + color[1]
43
+ $stderr.puts color[0] + NAME + "[#{label}] #{message_text}" + color[1]
39
44
  nil
40
45
  end
41
46
 
@@ -50,6 +50,7 @@ module ProMotion
50
50
  nav
51
51
  end
52
52
  self.navigationController.toolbarHidden = !args[:toolbar] unless args[:toolbar].nil?
53
+ self.navigationController.setNavigationBarHidden(args[:hide_nav_bar], animated: false) unless args[:hide_nav_bar].nil?
53
54
  end
54
55
 
55
56
  private
@@ -11,9 +11,9 @@ module ProMotion
11
11
  def screen_init(args = {})
12
12
  check_ancestry
13
13
  resolve_title
14
- tab_bar_setup
15
- set_attributes self, args
14
+ apply_properties(args)
16
15
  add_nav_bar(args) if args[:nav_bar]
16
+ tab_bar_setup
17
17
  try :screen_setup
18
18
  try :on_init
19
19
  PM.logger.deprecated "In #{self.class.to_s}, #on_create has been deprecated and removed. Use #screen_init instead." if respond_to?(:on_create)
@@ -146,6 +146,11 @@ module ProMotion
146
146
 
147
147
  private
148
148
 
149
+ def apply_properties(args)
150
+ reserved_args = [ :nav_bar, :hide_nav_bar, :hide_tab_bar, :animated, :close_all, :in_tab, :in_detail, :in_master, :to_screen ]
151
+ set_attributes self, args.dup.delete_if { |k,v| reserved_args.include?(k) }
152
+ end
153
+
149
154
  def tab_bar_setup
150
155
  self.tab_bar_item = self.class.send(:get_tab_bar_item)
151
156
  self.refresh_tab_bar_item if self.tab_bar_item
@@ -18,9 +18,11 @@ module ProMotion
18
18
  element.send("#{k}=", v)
19
19
  elsif v.is_a?(Array) && element.respond_to?("#{k}") && element.method("#{k}").arity == v.length
20
20
  element.send("#{k}", *v)
21
- else
22
- # Doesn't respond. Check if snake case.
23
- set_attribute(element, camelize(k), v) if k.to_s.include?("_")
21
+ elsif k.to_s.include?("_") # Snake case?
22
+ set_attribute(element, camelize(k), v)
23
+ else # Warn
24
+ PM.logger.debug "set_attribute: #{element.inspect} does not respond to #{k}=."
25
+ PM.logger.log("BACKTRACE", caller(0).join("\n"), :default) if PM.logger.level == :verbose
24
26
  end
25
27
  element
26
28
  end
@@ -23,14 +23,15 @@ 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 ]
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 ]
27
27
  if (data_cell.keys - whitelist).length > 0
28
- PM.logger.deprecated("In #{self.table_screen.class.to_s}#table_data, you should set :#{(data_cell.keys - whitelist).join(", :")} in a `style:` hash. See TableScreen documentation.")
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
30
30
  end
31
31
 
32
32
  def set_styles
33
- set_attributes self, data_cell[:style] if data_cell[:style]
33
+ data_cell[:properties] ||= data_cell[:style] || data_cell[:styles]
34
+ set_attributes self, data_cell[:properties] if data_cell[:properties]
34
35
  end
35
36
 
36
37
  def set_title
@@ -88,6 +89,7 @@ module ProMotion
88
89
  private
89
90
 
90
91
  def jm_image_cache?
92
+ return false if RUBYMOTION_ENV == 'test'
91
93
  return true if self.imageView.respond_to?("setImageWithURL:placeholder:")
92
94
  PM.logger.error "ProMotion Warning: to use remote_image with TableScreen you need to include the CocoaPod 'JMImageCache'."
93
95
  false
@@ -24,7 +24,7 @@ module ProMotion
24
24
 
25
25
  def cell(params={})
26
26
  params = index_path_to_section_index(params)
27
- table_section = self.section(params[:section])
27
+ table_section = params[:unfiltered] ? self.data[params[:section]] : self.section(params[:section])
28
28
  c = table_section[:cells].at(params[:index].to_i)
29
29
  set_data_cell_defaults c
30
30
  end
@@ -67,6 +67,7 @@ module ProMotion
67
67
  end
68
68
  data_cell[:cell_class] ||= PM::TableViewCell
69
69
  data_cell[:cell_identifier] ||= build_cell_identifier(data_cell)
70
+ data_cell[:properties] ||= data_cell[:style] || data_cell[:styles]
70
71
 
71
72
  data_cell[:accessory] = {
72
73
  view: data_cell[:accessory],
@@ -62,9 +62,17 @@ module ProMotion
62
62
  self.promotion_table_data.search_string
63
63
  end
64
64
 
65
- def update_table_view_data(data)
65
+ def update_table_view_data(data, args = {})
66
66
  self.promotion_table_data.data = data
67
- table_view.reloadData
67
+ if args[:index_paths]
68
+ args[:animation] ||= UITableViewRowAnimationNone
69
+
70
+ table_view.beginUpdates
71
+ table_view.reloadRowsAtIndexPaths(Array(args[:index_paths]), withRowAnimation: args[:animation])
72
+ table_view.endUpdates
73
+ else
74
+ table_view.reloadData
75
+ end
68
76
  @table_search_display_controller.searchResultsTableView.reloadData if searching?
69
77
  end
70
78
 
@@ -100,7 +108,7 @@ module ProMotion
100
108
  deletable_index_paths << index_path
101
109
  end
102
110
  end
103
- table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation:map_row_animation_symbol(animation)) if deletable_index_paths.length > 0
111
+ table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation: map_row_animation_symbol(animation)) if deletable_index_paths.length > 0
104
112
  end
105
113
 
106
114
  def table_view_cell(params={})
@@ -122,8 +130,11 @@ module ProMotion
122
130
  table_cell
123
131
  end
124
132
 
125
- def update_table_data
126
- self.update_table_view_data(self.table_data)
133
+ def update_table_data(args = {})
134
+ # Try and detect if the args param is a NSIndexPath or an array of them
135
+ args = { index_paths: args } if args.is_a?(NSIndexPath) || (args.is_a?(Array) && array_all_members_of?(args, NSIndexPath))
136
+
137
+ self.update_table_view_data(self.table_data, args)
127
138
  self.promotion_table_data.search(search_string) if searching?
128
139
  end
129
140
 
@@ -133,11 +144,11 @@ module ProMotion
133
144
  end
134
145
 
135
146
  # Number of cells
136
- def tableView(table_view, numberOfRowsInSection:section)
147
+ def tableView(table_view, numberOfRowsInSection: section)
137
148
  self.promotion_table_data.section_length(section)
138
149
  end
139
150
 
140
- def tableView(table_view, titleForHeaderInSection:section)
151
+ def tableView(table_view, titleForHeaderInSection: section)
141
152
  section = promotion_table_data.section(section)
142
153
  section && section[:title]
143
154
  end
@@ -149,29 +160,29 @@ module ProMotion
149
160
  nil
150
161
  end
151
162
 
152
- def tableView(table_view, cellForRowAtIndexPath:index_path)
163
+ def tableView(table_view, cellForRowAtIndexPath: index_path)
153
164
  table_view_cell(index_path: index_path)
154
165
  end
155
166
 
156
167
  def tableView(table_view, willDisplayCell: table_cell, forRowAtIndexPath: index_path)
157
168
  data_cell = self.promotion_table_data.cell(index_path: index_path)
158
- set_attributes table_cell, data_cell[:style] if data_cell[:style]
169
+ set_attributes table_cell, data_cell[:properties] if data_cell[:properties]
159
170
  table_cell.send(:will_display) if table_cell.respond_to?(:will_display)
160
171
  table_cell.send(:restyle!) if table_cell.respond_to?(:restyle!) # Teacup compatibility
161
172
  end
162
173
 
163
- def tableView(table_view, heightForRowAtIndexPath:index_path)
174
+ def tableView(table_view, heightForRowAtIndexPath: index_path)
164
175
  (self.promotion_table_data.cell(index_path: index_path)[:height] || table_view.rowHeight).to_f
165
176
  end
166
177
 
167
- def tableView(table_view, didSelectRowAtIndexPath:index_path)
178
+ def tableView(table_view, didSelectRowAtIndexPath: index_path)
168
179
  data_cell = self.promotion_table_data.cell(index_path: index_path)
169
180
  table_view.deselectRowAtIndexPath(index_path, animated: true) unless data_cell[:keep_selection] == true
170
181
  trigger_action(data_cell[:action], data_cell[:arguments], index_path) if data_cell[:action]
171
182
  end
172
183
 
173
184
  def tableView(table_view, editingStyleForRowAtIndexPath: index_path)
174
- data_cell = self.promotion_table_data.cell(index_path: index_path)
185
+ data_cell = self.promotion_table_data.cell(index_path: index_path, unfiltered: true)
175
186
  map_cell_editing_style(data_cell[:editing_style])
176
187
  end
177
188
 
@@ -181,18 +192,18 @@ module ProMotion
181
192
  end
182
193
  end
183
194
 
184
- def tableView(tableView, sectionForSectionIndexTitle:title, atIndex:index)
195
+ def tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index)
185
196
  return index unless ["{search}", UITableViewIndexSearch].include?(self.table_data_index[0])
186
197
 
187
198
  if index == 0
188
- tableView.scrollRectToVisible(CGRectMake(0.0, 0.0, 1.0, 1.0), animated:false)
199
+ tableView.scrollRectToVisible(CGRectMake(0.0, 0.0, 1.0, 1.0), animated: false)
189
200
  NSNotFound
190
201
  else
191
202
  index - 1
192
203
  end
193
204
  end
194
205
 
195
- def deleteRowsAtIndexPaths(index_paths, withRowAnimation:animation)
206
+ def deleteRowsAtIndexPaths(index_paths, withRowAnimation: animation)
196
207
  PM.logger.warn "ProMotion expects you to use 'delete_cell(index_paths, animation)'' instead of 'deleteRowsAtIndexPaths(index_paths, withRowAnimation:animation)'."
197
208
  delete_row(index_paths, animation)
198
209
  end
@@ -2,12 +2,17 @@ module ProMotion
2
2
  module Table
3
3
  module Utils
4
4
  def index_path_to_section_index(params)
5
- if params[:index_path]
5
+ if params.is_a?(Hash) && params[:index_path]
6
6
  params[:section] = params[:index_path].section
7
7
  params[:index] = params[:index_path].row
8
8
  end
9
9
  params
10
10
  end
11
+
12
+ # Determines if all members of an array are a certain class
13
+ def array_all_members_of?(arr, klass)
14
+ arr.select{ |e| e.is_a?(klass) }.length == arr.length
15
+ end
11
16
  end
12
17
  end
13
18
  end
@@ -38,13 +38,13 @@ module ProMotion
38
38
  item_image = nil
39
39
  end
40
40
 
41
- item = UITabBarItem.alloc.initWithTitle(title, image:item_image, tag:tag)
41
+ item = UITabBarItem.alloc.initWithTitle(title, image: item_image, tag: tag)
42
42
 
43
43
  if item_selected || item_unselected
44
44
  item.setFinishedSelectedImage(item_selected, withFinishedUnselectedImage: item_unselected)
45
45
  end
46
46
 
47
- return item
47
+ item
48
48
  end
49
49
 
50
50
  def create_tab_bar_item(tab={})
@@ -55,17 +55,24 @@ module ProMotion
55
55
  tab[:item] ||= tab[:icon]
56
56
  end
57
57
 
58
- title = "Untitled"
59
- title = tab[:title] if tab[:title]
60
- tab[:tag] ||= @current_tag ||= 0
61
- @current_tag = tab[:tag] + 1
58
+ unless tab[:system_item] || tab[:item]
59
+ PM.logger.warn("You must provide either a `system_item:` or custom `item:` in `tab_bar_item`")
60
+ abort
61
+ end
62
+
63
+ title = tab[:title] || "Untitled"
62
64
 
63
- tab_bar_item = UITabBarItem.alloc.initWithTabBarSystemItem(map_tab_symbol(tab[:system_item]), tag: tab[:tag]) if tab[:system_item]
64
- tab_bar_item = create_tab_bar_item_custom(title, tab[:item], tab[:tag]) if tab[:item]
65
+ tab_bar_item = UITabBarItem.alloc.initWithTabBarSystemItem(map_tab_symbol(tab[:system_item]), tag: current_tag) if tab[:system_item]
66
+ tab_bar_item = create_tab_bar_item_custom(title, tab[:item], current_tag) if tab[:item]
65
67
 
66
68
  tab_bar_item.badgeValue = tab[:badge_number].to_s unless tab[:badge_number].nil? || tab[:badge_number] <= 0
67
69
 
68
- return tab_bar_item
70
+ tab_bar_item
71
+ end
72
+
73
+ def current_tag
74
+ return @prev_tag = 0 unless @prev_tag
75
+ @prev_tag += 1
69
76
  end
70
77
 
71
78
  def replace_current_item(tab_bar_controller, view_controller: vc)
@@ -96,6 +103,7 @@ module ProMotion
96
103
  def tab_bar_item(args={})
97
104
  @tab_bar_item = args
98
105
  end
106
+
99
107
  def get_tab_bar_item
100
108
  @tab_bar_item
101
109
  end
@@ -1,3 +1,3 @@
1
1
  module ProMotion
2
- VERSION = "2.0.1" unless defined?(ProMotion::VERSION)
2
+ VERSION = "2.1.0.beta1" unless defined?(ProMotion::VERSION)
3
3
  end
@@ -36,7 +36,9 @@ module ProMotion
36
36
 
37
37
  def set_initial_content
38
38
  return unless self.respond_to?(:content)
39
- content.is_a?(NSURL) ? open_url(content) : set_content(content)
39
+ current_content = content
40
+ return unless current_content
41
+ current_content.is_a?(NSURL) ? open_url(current_content) : set_content(current_content)
40
42
  end
41
43
 
42
44
  def set_content(content)
@@ -1,6 +1,8 @@
1
1
  describe "ProMotion::Screen functionality" do
2
2
  tests PM::Screen
3
3
 
4
+ before { UIView.setAnimationDuration 0.01 }
5
+
4
6
  # Override controller to properly instantiate
5
7
  def controller
6
8
  rotate_device to: :portrait, button: :bottom
@@ -69,23 +71,22 @@ describe "ProMotion::Screen functionality" do
69
71
  end
70
72
 
71
73
  it "should call the on_back method on the root controller when navigating back" do
72
- @nav_screen = NavigationScreen.new nav_bar: true
73
- @presented_screen = PresentScreen.new
74
- @nav_screen.open @presented_screen
75
- @presented_screen.close
76
- @nav_screen.on_back_fired.should == true
74
+ presented_screen = PresentScreen.new
75
+ @controller.open presented_screen, animated: false
76
+ @controller.navigationController.viewControllers.should == [ @controller, presented_screen ]
77
+ presented_screen.close animated: false
78
+ @controller.on_back_fired.should == true
77
79
  end
78
80
 
79
81
  it "should call the correct on_back method when nesting screens" do
80
- @base_screen = NavigationScreen.new nav_bar: true
81
- @child_screen = @base_screen.open NavigationScreen.new
82
- @grandchild_screen = @child_screen.open NavigationScreen.new
82
+ child_screen = @controller.open NavigationScreen.new, animated: false
83
+ grandchild_screen = child_screen.open NavigationScreen.new, animated: false
83
84
 
84
85
  # start closing
85
- @grandchild_screen.close
86
- @child_screen.on_back_fired.should == true
87
- @child_screen.close
88
- @base_screen.on_back_fired.should == true
86
+ grandchild_screen.close animated: false
87
+ child_screen.on_back_fired.should == true
88
+ child_screen.close animated: false
89
+ @controller.on_back_fired.should == true
89
90
  end
90
91
 
91
92
  it "should allow opening and closing a modal screen" do
@@ -10,6 +10,7 @@ describe "Split screen functionality" do
10
10
  end
11
11
 
12
12
  before do
13
+ UIView.setAnimationDuration 0.01
13
14
  rotate_device to: :landscape, button: :right
14
15
  end
15
16
 
@@ -15,9 +15,15 @@ describe "ProMotion::TableScreen functionality" do
15
15
  end
16
16
 
17
17
  def confirmation_class
18
- TestHelper.ios7 ? UITableViewCellDeleteConfirmationButton : UITableViewCellDeleteConfirmationControl
18
+ TestHelper.ios7 ? "UITableViewCellDeleteConfirmationButton" : "UITableViewCellDeleteConfirmationControl"
19
19
  end
20
20
 
21
+ def table_label_class
22
+ TestHelper.ios7 ? "UILabel" : "UITableViewLabel"
23
+ end
24
+
25
+ before { UIView.setAnimationDuration 0.01 }
26
+
21
27
  after { @table_screen = nil }
22
28
 
23
29
  it "should have a navigation bar" do
@@ -31,7 +37,7 @@ describe "ProMotion::TableScreen functionality" do
31
37
 
32
38
  it "should add a new table cell on tap" do
33
39
  tap("Add New Row")
34
- view("Dynamically Added").class.should == UILabel
40
+ view("Dynamically Added").class.to_s.should == table_label_class
35
41
  end
36
42
 
37
43
  it "should do nothing when no action specified" do
@@ -47,7 +53,7 @@ describe "ProMotion::TableScreen functionality" do
47
53
  it "should delete the specified row from the table view on tap" do
48
54
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
49
55
  tap("Delete the row below")
50
- wait 0.3 do
56
+ wait 0.11 do
51
57
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 6
52
58
  end
53
59
  end
@@ -55,7 +61,7 @@ describe "ProMotion::TableScreen functionality" do
55
61
  it "should delete the specified row from the table view on tap with an animation" do
56
62
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
57
63
  tap("Delete the row below with an animation")
58
- wait 0.3 do
64
+ wait 0.11 do
59
65
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 6
60
66
  end
61
67
  end
@@ -66,12 +72,12 @@ describe "ProMotion::TableScreen functionality" do
66
72
  table_screen.cell_was_deleted.should != true
67
73
  flick("Just another deletable blank row", :to => :left)
68
74
 
69
- wait 0.25 do
75
+ wait 0.11 do
70
76
  # Tap the delete button
71
77
  view('Just another deletable blank row').superview.superview.subviews.each do |subview|
72
- if subview.class == confirmation_class
78
+ if subview.class.to_s == confirmation_class
73
79
  tap subview
74
- wait 0.25 do
80
+ wait 0.11 do
75
81
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 6
76
82
  table_screen.cell_was_deleted.should == true
77
83
  end
@@ -85,12 +91,12 @@ describe "ProMotion::TableScreen functionality" do
85
91
  table_screen.cell_was_deleted.should != true
86
92
  flick("A non-deletable blank row", :to => :left)
87
93
 
88
- wait 0.25 do
94
+ wait 0.11 do
89
95
  # Tap the delete button
90
96
  view('A non-deletable blank row').superview.superview.subviews.each do |subview|
91
97
  if subview.class == confirmation_class
92
98
  tap subview
93
- wait 0.25 do
99
+ wait 0.11 do
94
100
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
95
101
  table_screen.cell_was_deleted.should != false
96
102
  end
@@ -0,0 +1,52 @@
1
+ describe "ProMotion::TableScreen updating functionality" do
2
+ tests PM::UpdateTestTableScreen
3
+
4
+ before { UIView.setAnimationDuration 0.01 }
5
+
6
+ it 'should update a single row in the table view' do
7
+ table_screen = UpdateTestTableScreen.new
8
+ table_screen.make_more_cells
9
+ table_screen.update_table_data
10
+ table_screen.change_cells
11
+
12
+ table_screen.first_cell_title.should == "Cell 1"
13
+ table_screen.second_cell_title.should == "Cell 2"
14
+
15
+ table_screen.update_table_data(NSIndexPath.indexPathForRow(0, inSection:0))
16
+
17
+ table_screen.first_cell_title.should == "Cell A"
18
+ table_screen.second_cell_title.should == "Cell 2"
19
+ end
20
+
21
+ it 'should allow multiple formats of index paths to be passed' do
22
+ table_screen = UpdateTestTableScreen.new
23
+ table_screen.make_more_cells
24
+ table_screen.update_table_data
25
+ table_screen.change_cells
26
+
27
+ # Single NSIndexPath
28
+ Proc.new {
29
+ table_screen.update_table_data(NSIndexPath.indexPathForRow(0, inSection:0))
30
+ }.should.not.raise(StandardError)
31
+
32
+ # Array of NSIndexPaths
33
+ Proc.new {
34
+ table_screen.update_table_data([NSIndexPath.indexPathForRow(0, inSection:0), NSIndexPath.indexPathForRow(1, inSection:0)])
35
+ }.should.not.raise(StandardError)
36
+
37
+ # # Hash with single NSIndexPath
38
+ Proc.new {
39
+ table_screen.update_table_data({index_paths: NSIndexPath.indexPathForRow(0, inSection:0)})
40
+ }.should.not.raise(StandardError)
41
+
42
+ # Hash with array of NSIndexPaths
43
+ Proc.new {
44
+ table_screen.update_table_data({index_paths: [NSIndexPath.indexPathForRow(0, inSection:0), NSIndexPath.indexPathForRow(1, inSection:0)]})
45
+ }.should.not.raise(StandardError)
46
+
47
+ # Hash with NSIndexPath and row animation
48
+ Proc.new {
49
+ table_screen.update_table_data({index_paths: NSIndexPath.indexPathForRow(0, inSection:0), animation: UITableViewRowAnimationFade})
50
+ }.should.not.raise(StandardError)
51
+ end
52
+ end
@@ -1,7 +1,10 @@
1
1
  describe "ProMotion::TestWebScreen functionality" do
2
2
  extend WebStub::SpecHelpers
3
3
 
4
- before { disable_network_access! }
4
+ before do
5
+ disable_network_access!
6
+ UIView.setAnimationDuration 0.01
7
+ end
5
8
  after { enable_network_access! }
6
9
 
7
10
  def controller
@@ -1,6 +1,17 @@
1
1
  class TestHelper
2
+ def self.ios6
3
+ UIDevice.currentDevice.systemVersion.to_f >= 6.0 &&
4
+ UIDevice.currentDevice.systemVersion.to_f < 7.0
5
+ end
6
+
2
7
  def self.ios7
3
- UIDevice.currentDevice.systemVersion.to_f >= 7.0
8
+ UIDevice.currentDevice.systemVersion.to_f >= 7.0 &&
9
+ UIDevice.currentDevice.systemVersion.to_f < 8.0
10
+ end
11
+
12
+ def self.ios8
13
+ UIDevice.currentDevice.systemVersion.to_f >= 8.0 &&
14
+ UIDevice.currentDevice.systemVersion.to_f < 9.0
4
15
  end
5
16
  end
6
17
 
@@ -100,13 +100,13 @@ describe "screen helpers" do
100
100
 
101
101
  it "#push_view_controller should use the default navigation controller if not provided" do
102
102
  vcs = @screen.navigationController.viewControllers
103
- @screen.push_view_controller @second_vc
103
+ @screen.push_view_controller @second_vc, @screen.navigationController, false
104
104
  @screen.navigationController.viewControllers.count.should == vcs.count + 1
105
105
  end
106
106
 
107
107
  it "#push_view_controller should use a provided navigation controller" do
108
108
  second_nav_controller = UINavigationController.alloc.initWithRootViewController @screen
109
- @screen.push_view_controller @second_vc, second_nav_controller
109
+ @screen.push_view_controller @second_vc, second_nav_controller, false
110
110
  second_nav_controller.viewControllers.count.should == 2
111
111
  end
112
112
 
@@ -123,13 +123,14 @@ describe "screen helpers" do
123
123
  end
124
124
 
125
125
  it "should apply properties when opening a new screen" do
126
- new_screen = @screen.send(:set_up_screen_for_open, BasicScreen, { title: 'Some Title', modal: true, hide_tab_bar: true, nav_bar: true })
126
+ new_screen = @screen.send(:set_up_screen_for_open, BasicScreen, { title: 'Some Title', modal: true, hide_tab_bar: true, nav_bar: true, hide_nav_bar: true })
127
127
 
128
128
  new_screen.parent_screen.should == @screen
129
129
  new_screen.title.should == 'Some Title'
130
130
  new_screen.modal?.should == true
131
131
  new_screen.hidesBottomBarWhenPushed.should == true
132
132
  new_screen.nav_bar?.should == true
133
+ new_screen.navigationController.isNavigationBarHidden.should == true
133
134
  end
134
135
 
135
136
  it "should present the navigationController when showing a modal screen" do
@@ -199,7 +200,7 @@ describe "screen helpers" do
199
200
 
200
201
  it "should ignore its own navigation controller if current screen has a navigation controller" do
201
202
  basic = BasicScreen.new(nav_bar: true) # creates a dangling nav_bar that will be discarded.
202
- screen = @screen.open basic
203
+ screen = @screen.open basic, animated: false
203
204
  screen.should.be.kind_of BasicScreen
204
205
  basic.navigationController.should == @screen.navigationController
205
206
  end
@@ -301,13 +302,13 @@ describe "screen helpers" do
301
302
 
302
303
  it "#send_on_return should pass args to the first screen with :root" do
303
304
  first_screen = HomeScreen.new(nav_bar: true)
304
- second_screen = first_screen.open(BasicScreen)
305
- second_screen.open @screen
305
+ second_screen = first_screen.open(BasicScreen, animated: false)
306
+ second_screen.open @screen, animated: false
306
307
 
307
308
 
308
309
  second_screen.stub!(:on_return) { |args| should.flunk "shouldn't call on_return on second_screen!" }
309
310
  first_screen.mock!(:on_return) { |args| args[:key].should == :value }
310
- @screen.close({ key: :value, to_screen: :root })
311
+ @screen.close key: :value, to_screen: :root, animated: false
311
312
  end
312
313
  end
313
314
 
@@ -60,7 +60,7 @@ describe "screen properties" do
60
60
  # Issue https://github.com/clearsightstudio/ProMotion/issues/109
61
61
  it "#should_autorotate should fire when shouldAutorotate fires when in a navigation bar" do
62
62
  parent_screen = BasicScreen.new(nav_bar: true)
63
- parent_screen.open @screen
63
+ parent_screen.open @screen, animated: false
64
64
  @screen.mock!(:should_autorotate) { true.should == true }
65
65
  parent_screen.navigationController.shouldAutorotate
66
66
  end
@@ -31,14 +31,14 @@ describe "split screen `open` functionality" do
31
31
  end
32
32
 
33
33
  it "should open a new screen in the master view's navigation controller" do
34
- screen = @master_screen.open @detail_screen_2
34
+ screen = @master_screen.open @detail_screen_2, animated: false
35
35
  @split_screen.detail_screen.should == @detail_screen_1 # no change
36
36
  @master_screen.navigationController.topViewController.should == @detail_screen_2
37
37
  screen.should == @detail_screen_2
38
38
  end
39
39
 
40
40
  it "should open a new modal screen in the detail view" do
41
- screen = @detail_screen_1.open @detail_screen_2, modal: true
41
+ screen = @detail_screen_1.open @detail_screen_2, modal: true, animated: false
42
42
  @split_screen.detail_screen.should == @detail_screen_1
43
43
  @detail_screen_1.presentedViewController.should == (@detail_screen_2.navigationController || @detail_screen_2)
44
44
  screen.should == @detail_screen_2
@@ -47,7 +47,7 @@ describe "split screen `open` functionality" do
47
47
  it "should not interfere with normal non-split screen navigation" do
48
48
  home = HomeScreen.new(nav_bar: true)
49
49
  child = BasicScreen.new
50
- screen = home.open child, in_detail: true, in_master: true
50
+ screen = home.open child, in_detail: true, in_master: true, animated: false
51
51
  home.navigationController.topViewController.should == child
52
52
  screen.should == child
53
53
  end
@@ -23,6 +23,13 @@ describe "PM::Tabs" do
23
23
  tab_bar.viewControllers.length.should == 4
24
24
  end
25
25
 
26
+ it "should have correct tags on each tabBarItem" do
27
+ @screen1.tabBarItem.tag.should == 0
28
+ @screen2.tabBarItem.tag.should == 1
29
+ @screen3.tabBarItem.tag.should == 2
30
+ @screen4.tabBarItem.tag.should == 3
31
+ end
32
+
26
33
  it "should have the right screens in the right places" do
27
34
  tab_bar.viewControllers[0].should == @screen1.navigationController
28
35
  tab_bar.viewControllers[1].should == @screen2.navigationController
@@ -28,7 +28,7 @@ describe "tab bar functionality" do
28
28
  it "should have set the others to their respective titles" do
29
29
  @tab_bar.tabBar.items[1].title.should == "Basic"
30
30
  @tab_bar.tabBar.items[2].title.should == "Home"
31
- @tab_bar.tabBar.items[3].title.should == "TestTableScreen"
31
+ @tab_bar.tabBar.items[3].title.should == "Test tab title"
32
32
  end
33
33
 
34
34
  it "should allow changing the tab bar item with set_tab_bar_item" do
@@ -5,7 +5,8 @@ describe "PM::Table module" do
5
5
  end
6
6
 
7
7
  def custom_cell
8
- @image = UIImage.imageNamed("list")
8
+ @image ||= UIImage.imageNamed("list")
9
+ @pattern_image_color ||= UIColor.colorWithPatternImage(@image)
9
10
  cell_factory({
10
11
  title: "Crazy Full Featured Cell",
11
12
  subtitle: "This is way too huge..see note",
@@ -29,13 +30,29 @@ describe "PM::Table module" do
29
30
  size: 50,
30
31
  radius: 15
31
32
  },
32
- style: {
33
- masks_to_bounds: true,
34
- background_color: UIColor.colorWithPatternImage(@image)
33
+ properties: {
34
+ content_view: {
35
+ background_color: @pattern_image_color,
36
+ },
37
+ layer: {
38
+ masks_to_bounds: true,
39
+ },
35
40
  }
36
41
  })
37
42
  end
38
43
 
44
+ def default_cell_height
45
+ return UITableViewAutomaticDimension if TestHelper.ios8
46
+ return 44.0 if TestHelper.ios7
47
+ end
48
+
49
+ def default_header_height
50
+ # Thanks, Apple.
51
+ return -1.0 if TestHelper.ios8
52
+ return 23.0 if TestHelper.ios7
53
+ return 22.0 if TestHelper.ios6
54
+ end
55
+
39
56
  before do
40
57
  @subject = TestTableScreen.new
41
58
  @subject.mock! :table_data do
@@ -44,7 +61,7 @@ describe "PM::Table module" do
44
61
  },{
45
62
  title: "Table cell group 2", cells: [ cell_factory ]
46
63
  },{
47
- title: "Table cell group 3", cells: [ cell_factory(title: "3-1"), cell_factory({title: "3-2", style: { background_color: UIColor.blueColor } }) ]
64
+ title: "Table cell group 3", cells: [ cell_factory(title: "3-1"), cell_factory({title: "3-2", properties: { background_color: UIColor.blueColor } }) ]
48
65
  },{
49
66
  title: "Table cell group 4", cells: [ custom_cell, cell_factory(title: "4-2"), cell_factory(title: "4-3"), cell_factory(title: "4-4") ]
50
67
  },{
@@ -101,7 +118,7 @@ describe "PM::Table module" do
101
118
  end
102
119
 
103
120
  it "should return the table's cell height if none is given" do
104
- @subject.tableView(@subject.table_view, heightForRowAtIndexPath:@ip).should == 44.0 # Built-in default
121
+ @subject.tableView(@subject.table_view, heightForRowAtIndexPath:@ip).should == default_cell_height
105
122
  end
106
123
 
107
124
  it "should allow setting a custom cell height" do
@@ -140,11 +157,12 @@ describe "PM::Table module" do
140
157
 
141
158
  it "should set a custom cell background image" do
142
159
  @image.should.not.be.nil
143
- ip = NSIndexPath.indexPathForRow(0, inSection: 3) # Cell 2-1
160
+ ip = NSIndexPath.indexPathForRow(0, inSection: 3) # Cell 4-1
144
161
  cell = @subject.tableView(@subject.table_view, cellForRowAtIndexPath: ip)
145
162
  cell.should.be.kind_of(UITableViewCell)
146
- cell.backgroundColor.should.be.kind_of(UIColor)
147
- cell.backgroundColor.should == UIColor.colorWithPatternImage(@image)
163
+ cell.layer.masksToBounds.should == true
164
+ cell.contentView.backgroundColor.should.be.kind_of(UIColor)
165
+ cell.contentView.backgroundColor.should == @pattern_image_color
148
166
  end
149
167
 
150
168
  it "should set a custom cell background color" do
@@ -162,8 +180,7 @@ describe "PM::Table module" do
162
180
  end
163
181
 
164
182
  it "should use the default section height if none is specified" do
165
- header_height = (UIDevice.currentDevice.systemVersion.to_f >= 7.0) ? 23.0 : 22.0
166
- @subject.tableView(@subject.table_view, heightForHeaderInSection:4).should == header_height # Built-in default
183
+ @subject.tableView(@subject.table_view, heightForHeaderInSection:4).should == default_header_height
167
184
  end
168
185
 
169
186
  it "should use the set title_view_height if one is specified" do
@@ -112,20 +112,6 @@ describe "table screens" do
112
112
  end
113
113
 
114
114
  describe "test PM::TableScreen's updating functionality" do
115
- before do
116
- class UpdateTestTableScreen < PM::TableScreen
117
- def table_data; @table_data ||= []; end
118
- def on_load
119
- @table_data = [{cells: []}]
120
- update_table_data
121
- end
122
-
123
- def make_more_cells
124
- @table_data = [{cells: [{title: "Cell 1"},{title: "Cell 2"}]}]
125
- end
126
- end
127
- end
128
-
129
115
  it 'should update the table data when update_table_data is called' do
130
116
  @screen = UpdateTestTableScreen.new
131
117
  @screen.tableView(@screen.tableView, numberOfRowsInSection:0).should == 0
@@ -0,0 +1,34 @@
1
+ describe "PM::Table utils" do
2
+
3
+ before do
4
+ @subject = TestTableScreen.new
5
+ @subject.on_load
6
+ @subject.update_table_data
7
+ end
8
+
9
+ it "should convert an index path to a section index" do
10
+ index_path = NSIndexPath.indexPathForRow(12, inSection:2)
11
+ given = {index_path: index_path}
12
+ expected = {
13
+ index_path: index_path,
14
+ section: 2,
15
+ index: 12
16
+ }
17
+
18
+ @subject.index_path_to_section_index(given).should == expected
19
+ end
20
+
21
+ it "return the original param when converting an index path with incorrect values" do
22
+ @subject.index_path_to_section_index(17).should == 17
23
+ end
24
+
25
+ it "should properly determine if all members of an array are the same class" do
26
+ @subject.array_all_members_of?([1, 2, 3, 4], Fixnum).should == true
27
+ @subject.array_all_members_of?(["string", 'string2'], String).should == true
28
+ @subject.array_all_members_of?([:sym1, :sym2, :sym3], Symbol).should == true
29
+
30
+ @subject.array_all_members_of?([1, 2, 3, 4, 'String'], Fixnum).should == false
31
+ @subject.array_all_members_of?([4.4, 2], Fixnum).should == false
32
+ end
33
+
34
+ end
@@ -19,7 +19,7 @@ describe "PM::TableViewCellModule" do
19
19
  radius: 15
20
20
  },
21
21
  selection_style: :gray,
22
- style: {
22
+ properties: {
23
23
  layer: {
24
24
  masks_to_bounds: true
25
25
  },
@@ -48,7 +48,7 @@ describe "PM::TableViewCellModule" do
48
48
  {
49
49
  title: "",
50
50
  cells: [
51
- { title: "Test 1", style: { accessory_type: UITableViewCellStateShowingEditControlMask } },
51
+ { title: "Test 1", properties: { accessory_type: UITableViewCellStateShowingEditControlMask } },
52
52
  custom_cell,
53
53
  { title: "Test2", accessory: { view: button } },
54
54
  attributed_cell
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.0.1
4
+ version: 2.1.0.beta1
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-09-04 00:00:00.000000000 Z
13
+ date: 2014-10-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: methadone
@@ -18,28 +18,28 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '1.4'
21
+ version: '1.7'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '1.4'
28
+ version: '1.7'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: webstub
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '1.0'
35
+ version: '1.1'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '1.0'
42
+ version: '1.1'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: motion-stump
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +134,7 @@ files:
134
134
  - spec/functional/func_screen_spec.rb
135
135
  - spec/functional/func_split_screen_spec.rb
136
136
  - spec/functional/func_table_screen_spec.rb
137
+ - spec/functional/func_table_screen_updating_spec.rb
137
138
  - spec/functional/func_web_screen_spec.rb
138
139
  - spec/helpers/test_helper.rb
139
140
  - spec/unit/delegate_spec.rb
@@ -154,6 +155,7 @@ files:
154
155
  - spec/unit/tables/table_indexable_spec.rb
155
156
  - spec/unit/tables/table_module_spec.rb
156
157
  - spec/unit/tables/table_screen_spec.rb
158
+ - spec/unit/tables/table_utils_spec.rb
157
159
  - spec/unit/tables/table_view_cell_spec.rb
158
160
  - spec/unit/view_helper_spec.rb
159
161
  - spec/unit/view_title_screen.rb
@@ -173,12 +175,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
175
  version: '0'
174
176
  required_rubygems_version: !ruby/object:Gem::Requirement
175
177
  requirements:
176
- - - ">="
178
+ - - ">"
177
179
  - !ruby/object:Gem::Version
178
- version: '0'
180
+ version: 1.3.1
179
181
  requirements: []
180
182
  rubyforge_project:
181
- rubygems_version: 2.2.2
183
+ rubygems_version: 2.4.2
182
184
  signing_key:
183
185
  specification_version: 4
184
186
  summary: ProMotion is a fast way to get started building RubyMotion apps. Instead
@@ -190,6 +192,7 @@ test_files:
190
192
  - spec/functional/func_screen_spec.rb
191
193
  - spec/functional/func_split_screen_spec.rb
192
194
  - spec/functional/func_table_screen_spec.rb
195
+ - spec/functional/func_table_screen_updating_spec.rb
193
196
  - spec/functional/func_web_screen_spec.rb
194
197
  - spec/helpers/test_helper.rb
195
198
  - spec/unit/delegate_spec.rb
@@ -210,8 +213,8 @@ test_files:
210
213
  - spec/unit/tables/table_indexable_spec.rb
211
214
  - spec/unit/tables/table_module_spec.rb
212
215
  - spec/unit/tables/table_screen_spec.rb
216
+ - spec/unit/tables/table_utils_spec.rb
213
217
  - spec/unit/tables/table_view_cell_spec.rb
214
218
  - spec/unit/view_helper_spec.rb
215
219
  - spec/unit/view_title_screen.rb
216
220
  - spec/unit/web_spec.rb
217
- has_rdoc: