ProMotion 0.7.5 → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.travis.yml CHANGED
@@ -3,4 +3,4 @@ gemfile:
3
3
  - Gemfile
4
4
  before_script: bundle install
5
5
  script: bundle exec rake spec
6
- bump: 2
6
+ bump: 3
data/README.md CHANGED
@@ -1,8 +1,38 @@
1
- # ProMotion [![Build Status](https://travis-ci.org/clearsightstudio/ProMotion.png)](https://travis-ci.org/clearsightstudio/ProMotion)
1
+ # 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)
2
2
 
3
3
  ## A new way to easily build RubyMotion apps.
4
4
 
5
- ProMotion is a RubyMotion gem that makes iOS development more like Ruby and less like Objective-C.
5
+ ProMotion is a RubyMotion gem that makes iOS development more like Ruby and less like Objective-C. It introduces a clean, Ruby-style syntax for building screens that is easy to learn and remember.
6
+
7
+ ```ruby
8
+ class AppDelegate < PM::Delegate
9
+ def on_load(app, options)
10
+ open RootScreen.new(nav_bar: true)
11
+ end
12
+ end
13
+
14
+ class RootScreen < PM::Screen
15
+ title "Root Screen"
16
+
17
+ def push_new_screen
18
+ open NewScreen
19
+ end
20
+ end
21
+
22
+ class NewScreen < PM::TableScreen
23
+ title "Table Screen"
24
+
25
+ def table_data
26
+ [{
27
+ cells: [
28
+ { title: "About this app", action: :tapped_about },
29
+ { title: "Log out", action: :log_out }
30
+ ]
31
+ }]
32
+ end
33
+ end
34
+ ```
35
+
6
36
 
7
37
  Featured on the RubyMotion blog: [http://blog.rubymotion.com/post/50523137515/introducing-promotion-a-full-featured-rubymotion](http://blog.rubymotion.com/post/50523137515/introducing-promotion-a-full-featured-rubymotion)
8
38
 
@@ -506,6 +536,7 @@ incorporated.
506
536
  * Jamon Holmgren: [@jamonholmgren](https://twitter.com/jamonholmgren)
507
537
  * Silas Matson: [@silasjmatson](https://twitter.com/silasjmatson)
508
538
  * Matt Brewer: [@macfanatic](https://twitter.com/macfanatic)
539
+ * Mark Rickert: [@markrickert](https://twitter.com/markrickert)
509
540
  * [Many others](https://github.com/clearsightstudio/ProMotion/graphs/contributors)
510
- * If you really want to know, run `git shortlog -s -n -e`
541
+ * Run `git shortlog -s -n -e` to see everyone who has contributed.
511
542
 
@@ -69,9 +69,9 @@ module ProMotion
69
69
  height
70
70
  end
71
71
 
72
- def closest_parent(type)
72
+ def closest_parent(type, this_view = nil)
73
73
  # iterate up the view hierarchy to find the parent element of "type" containing this view
74
- this_view = self.superview
74
+ this_view ||= self.superview
75
75
  while this_view != nil do
76
76
  return this_view if this_view.is_a? type
77
77
  this_view = this_view.superview
@@ -2,13 +2,13 @@ module ProMotion
2
2
  module ScreenNavigation
3
3
 
4
4
  def open_screen(screen, args = {})
5
+ args = { in_detail: false, in_master: false, close_all: false, modal: false, in_tab: false, animated: true }.merge args
5
6
 
6
7
  # Apply properties to instance
7
- screen = setup_screen_for_open(screen, args)
8
+ screen = set_up_screen_for_open(screen, args)
8
9
  ensure_wrapper_controller_in_place(screen, args)
9
10
 
10
11
  screen.send(:on_load) if screen.respond_to?(:on_load)
11
- animated = args[:animated] || true
12
12
 
13
13
  if args[:in_detail] && self.split_screen
14
14
  self.split_screen.detail_screen = screen
@@ -20,7 +20,7 @@ module ProMotion
20
20
  open_root_screen screen
21
21
 
22
22
  elsif args[:modal]
23
- present_modal_view_controller screen, animated
23
+ present_modal_view_controller screen, args[:animated]
24
24
 
25
25
  elsif args[:in_tab] && self.tab_bar
26
26
  present_view_controller_in_tab_bar_controller screen, args[:in_tab]
@@ -51,7 +51,7 @@ module ProMotion
51
51
  def close_screen(args = {})
52
52
  args ||= {}
53
53
  args = { sender: args } unless args.is_a?(Hash)
54
- args[:animated] ||= true
54
+ args[:animated] = true unless args.has_key?(:animated)
55
55
 
56
56
  if self.modal?
57
57
  close_modal_screen args
@@ -69,7 +69,7 @@ module ProMotion
69
69
 
70
70
  def send_on_return(args = {})
71
71
  if self.parent_screen && self.parent_screen.respond_to?(:on_return)
72
- if args
72
+ if args && self.parent_screen.method(:on_return).arity != 0
73
73
  self.parent_screen.send(:on_return, args)
74
74
  else
75
75
  self.parent_screen.send(:on_return)
@@ -88,20 +88,23 @@ module ProMotion
88
88
  end
89
89
  nav_controller ||= self.navigation_controller
90
90
  vc.first_screen = false if vc.respond_to?(:first_screen=)
91
+ vc.navigation_controller = nav_controller if vc.respond_to?(:navigation_controller=)
91
92
  nav_controller.pushViewController(vc, animated: true)
92
93
  end
93
94
 
94
95
  protected
95
96
 
96
- def setup_screen_for_open(screen, args={})
97
+ def set_up_screen_for_open(screen, args={})
97
98
 
98
99
  # Instantiate screen if given a class
99
100
  screen = screen.new if screen.respond_to?(:new)
101
+
102
+ # Set parent
103
+ screen.parent_screen = self if screen.respond_to?(:parent_screen=)
100
104
 
101
- # Set parent, title & modal properties
102
- screen.parent_screen = self if screen.respond_to?("parent_screen=")
103
- screen.title = args[:title] if args[:title] && screen.respond_to?("title=")
104
- screen.modal = args[:modal] if args[:modal] && screen.respond_to?("modal=")
105
+ # Set title & modal properties
106
+ screen.title = args[:title] if args[:title] && screen.respond_to?(:title=)
107
+ screen.modal = args[:modal] if args[:modal] && screen.respond_to?(:modal=)
105
108
 
106
109
  # Hide bottom bar?
107
110
  screen.hidesBottomBarWhenPushed = args[:hide_tab_bar] == true
@@ -115,7 +118,7 @@ module ProMotion
115
118
  end
116
119
 
117
120
  def ensure_wrapper_controller_in_place(screen, args={})
118
- unless args[:close_all] || args[:modal]
121
+ unless args[:close_all] || args[:modal] || args[:in_detail] || args[:in_master]
119
122
  screen.navigation_controller ||= self.navigation_controller if screen.respond_to?("navigation_controller=")
120
123
  screen.tab_bar ||= self.tab_bar if screen.respond_to?("tab_bar=")
121
124
  end
@@ -144,14 +147,14 @@ module ProMotion
144
147
  end
145
148
 
146
149
  def close_modal_screen(args={})
147
- args[:animated] ||= true
150
+ args[:animated] = true unless args.has_key?(:animated)
148
151
  self.parent_screen.dismissViewControllerAnimated(args[:animated], completion: lambda {
149
152
  send_on_return(args)
150
153
  })
151
154
  end
152
155
 
153
156
  def close_nav_screen(args={})
154
- args[:animated] ||= true
157
+ args[:animated] = true unless args.has_key?(:animated)
155
158
  if args[:to_screen] && args[:to_screen].is_a?(UIViewController)
156
159
  self.parent_screen = args[:to_screen]
157
160
  self.navigation_controller.popToViewController(args[:to_screen], animated: args[:animated])
@@ -162,3 +165,6 @@ module ProMotion
162
165
 
163
166
  end
164
167
  end
168
+
169
+
170
+
@@ -103,18 +103,19 @@ module ProMotion
103
103
 
104
104
  def bar_button_item(button_type, args)
105
105
  case button_type
106
- when UIBarButtonItem
107
- button_type
108
- when UIImage
109
- UIBarButtonItem.alloc.initWithImage(button_type, style: args[:style], target: args[:target], action: args[:action])
110
- when String
111
- UIBarButtonItem.alloc.initWithTitle(button_type, style: args[:style], target: args[:target], action: args[:action])
106
+ when UIBarButtonItem
107
+ button_type
108
+ when UIImage
109
+ UIBarButtonItem.alloc.initWithImage(button_type, style: args[:style], target: args[:target], action: args[:action])
110
+ when String
111
+ UIBarButtonItem.alloc.initWithTitle(button_type, style: args[:style], target: args[:target], action: args[:action])
112
+ else
113
+ if args[:system_icon]
114
+ UIBarButtonItem.alloc.initWithBarButtonSystemItem(args[:system_icon], target: args[:target], action: args[:action])
112
115
  else
113
- if args[:system_icon]
114
- UIBarButtonItem.alloc.initWithBarButtonSystemItem(args[:system_icon], target: args[:target], action: args[:action])
115
- else
116
- PM.logger.error("Please supply a title string, a UIImage or :system.")
117
- end
116
+ PM.logger.error("Please supply a title string, a UIImage or :system.")
117
+ nil
118
+ end
118
119
  end
119
120
  end
120
121
 
@@ -10,10 +10,10 @@ module ProMotion
10
10
  search_bar.placeholder = params[:search_bar][:placeholder]
11
11
  end
12
12
 
13
- @contacts_search_display_controller = UISearchDisplayController.alloc.initWithSearchBar(search_bar, contentsController: params[:content_controller])
14
- @contacts_search_display_controller.delegate = params[:delegate]
15
- @contacts_search_display_controller.searchResultsDataSource = params[:data_source]
16
- @contacts_search_display_controller.searchResultsDelegate = params[:search_results_delegate]
13
+ @table_search_display_controller = UISearchDisplayController.alloc.initWithSearchBar(search_bar, contentsController: params[:content_controller])
14
+ @table_search_display_controller.delegate = params[:delegate]
15
+ @table_search_display_controller.searchResultsDataSource = params[:data_source]
16
+ @table_search_display_controller.searchResultsDelegate = params[:search_results_delegate]
17
17
 
18
18
  self.table_view.tableHeaderView = search_bar
19
19
  end
@@ -69,8 +69,10 @@ module ProMotion
69
69
  end
70
70
 
71
71
  def accessory_toggled_switch(switch)
72
- table_cell = switch.superview
73
- index_path = table_cell.superview.indexPathForCell(table_cell)
72
+ # table_cell = switch.superview
73
+ table_cell = closest_parent(UITableViewCell, switch)
74
+ # index_path = table_cell.superview.indexPathForCell(table_cell)
75
+ index_path = closest_parent(UITableView, table_cell).indexPathForCell(table_cell)
74
76
 
75
77
  data_cell = cell_at_section_and_index(index_path.section, index_path.row)
76
78
  data_cell[:accessory][:arguments] = {} unless data_cell[:accessory][:arguments]
@@ -106,7 +108,11 @@ module ProMotion
106
108
 
107
109
  # Set table_data_index if you want the right hand index column (jumplist)
108
110
  def sectionIndexTitlesForTableView(table_view)
109
- self.table_data_index if self.respond_to?(:table_data_index)
111
+ if @promotion_table_data.filtered
112
+ nil
113
+ else
114
+ self.table_data_index if self.respond_to?(:table_data_index)
115
+ end
110
116
  end
111
117
 
112
118
  def tableView(table_view, cellForRowAtIndexPath:index_path)
@@ -1,3 +1,3 @@
1
1
  module ProMotion
2
- VERSION = "0.7.5" unless defined?(ProMotion::VERSION)
2
+ VERSION = "0.7.6" unless defined?(ProMotion::VERSION)
3
3
  end
@@ -55,12 +55,6 @@ describe "ProMotion::TestTableScreen functionality" do
55
55
  @controller.tap_counter.should == 1
56
56
  end
57
57
 
58
- it "should call the method with arguments when the switch is flipped" do
59
- @controller.scroll_to_bottom
60
- tap "switch_2"
61
- @controller.tap_counter.should == 3
62
- end
63
-
64
58
  it "should call the method with arguments when the switch is flipped and when the cell is tapped" do
65
59
  @controller.scroll_to_bottom
66
60
  tap "switch_3"
@@ -70,4 +64,10 @@ describe "ProMotion::TestTableScreen functionality" do
70
64
  @controller.tap_counter.should == 13
71
65
  end
72
66
 
67
+ it "should call the method with arguments when the switch is flipped" do
68
+ @controller.scroll_to_bottom
69
+ tap "switch_2"
70
+ @controller.tap_counter.should == 3
71
+ end
72
+
73
73
  end
@@ -108,11 +108,11 @@ describe "screen helpers" do
108
108
  describe "opening a screen" do
109
109
 
110
110
  it "should create an instance from class when opening a new screen" do
111
- @screen.send(:setup_screen_for_open, BasicScreen).should.be.instance_of BasicScreen
111
+ @screen.send(:set_up_screen_for_open, BasicScreen).should.be.instance_of BasicScreen
112
112
  end
113
113
 
114
114
  it "should apply properties when opening a new screen" do
115
- new_screen = @screen.send(:setup_screen_for_open, BasicScreen, title: 'Some Title', modal: true, hide_tab_bar: true, nav_bar: true)
115
+ new_screen = @screen.send(:set_up_screen_for_open, BasicScreen, title: 'Some Title', modal: true, hide_tab_bar: true, nav_bar: true)
116
116
 
117
117
  new_screen.parent_screen.should == @screen
118
118
  new_screen.title.should == 'Some Title'
@@ -122,7 +122,7 @@ describe "screen helpers" do
122
122
  end
123
123
 
124
124
  it "should present the #main_controller when showing a modal screen" do
125
- new_screen = @screen.send(:setup_screen_for_open, BasicScreen, modal: true)
125
+ new_screen = @screen.send(:set_up_screen_for_open, BasicScreen, modal: true)
126
126
 
127
127
  @screen.mock!('presentModalViewController:animated:') do |vc, animated|
128
128
  vc.should == new_screen.main_controller
@@ -151,7 +151,7 @@ describe "screen helpers" do
151
151
  end
152
152
  @screen.open BasicScreen, modal: true
153
153
  end
154
-
154
+
155
155
  it "should present a modal screen if open_modal is used" do
156
156
  @screen.mock!(:present_modal_view_controller) do |screen, animated|
157
157
  screen.should.be.instance_of BasicScreen
@@ -160,6 +160,16 @@ describe "screen helpers" do
160
160
  @screen.open_modal BasicScreen
161
161
  end
162
162
 
163
+ it "should respect animated property of opening modal screens" do
164
+ new_screen = @screen.send(:set_up_screen_for_open, BasicScreen)
165
+
166
+ @screen.mock!('presentModalViewController:animated:') do |vc, animated|
167
+ animated.should == false
168
+ end
169
+
170
+ @screen.send(:open, new_screen, animated: false, modal: true)
171
+ end
172
+
163
173
  it "should open screen in tab bar if :in_tab is provided" do
164
174
  @screen.stub!(:tab_bar, return: true)
165
175
  @screen.mock!(:present_view_controller_in_tab_bar_controller) do |screen, tab_name|
@@ -173,6 +183,14 @@ describe "screen helpers" do
173
183
  @screen.mock!(:push_view_controller) { |vc| vc.should.be.instance_of BasicScreen }
174
184
  @screen.open BasicScreen
175
185
  end
186
+
187
+ it "should ignore its own navigation controller if current screen has a navigation controller" do
188
+ basic = BasicScreen.new(nav_bar: true) # creates a dangling nav_bar that will be discarded.
189
+ @screen.open basic
190
+ basic.navigationController.should == @screen.navigationController
191
+ basic.navigation_controller.should == @screen.navigationController
192
+ @screen.navigation_controller.should == @screen.navigationController
193
+ end
176
194
 
177
195
  it "should open the provided view controller as root view if no other conditions are met" do
178
196
  parent_screen = HomeScreen.new
@@ -213,6 +231,18 @@ describe "screen helpers" do
213
231
  @screen.close
214
232
  end
215
233
 
234
+ it "should respect animated value for closing modal screens" do
235
+ parent_screen = HomeScreen.new
236
+ @screen.parent_screen = parent_screen
237
+ @screen.modal = true
238
+
239
+ parent_screen.mock!('dismissViewControllerAnimated:completion:') do |animated, completion|
240
+ animated.should == false
241
+ end
242
+
243
+ @screen.send(:close, animated: false)
244
+ end
245
+
216
246
  it "#close should pop from the navigation controller" do
217
247
  @screen.navigation_controller.mock!(:popViewControllerAnimated) { |animated| animated.should == true }
218
248
  @screen.close
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: 0.7.5
4
+ version: 0.7.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-06-11 00:00:00.000000000 Z
14
+ date: 2013-06-14 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: motion-stump