ProMotion 2.2.2 → 2.3.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: c43b2e73403d46846ef391c38eff15acd4239324
4
- data.tar.gz: aa5c91f5332d8764690dd8de33c0bc4c0f59ef9f
3
+ metadata.gz: be839599d650130f82f0fa241e88bf2b76fc4964
4
+ data.tar.gz: b1f0799f8f393b3de1d8b60307b6e256225682c3
5
5
  SHA512:
6
- metadata.gz: d54c1e1f6fc6c2d983505aad1df54faa34d711a3e1662727c396c0ae4b524d40eea5bdcf8b43a82b8287b216d2f3c67d2d92730472a3e9738833a1b338d71b51
7
- data.tar.gz: d6cc272e0f8be4c6282c1d5bdf03ec4e42244f0c380802f8dcb144351ae8901be5f80470c765fcc5fec026f1b152f610e5702214b3ea64977c88a2b7f66f3490
6
+ metadata.gz: 3fedb2aff2f4df877da8a384599ea6aaec3ef572c479016a7fc84d8447b4089459a88ef1611502df27668bd29a2fa25f597d7c83333ffeae5c26091b43a1e88c
7
+ data.tar.gz: 54c0ccb64e0eb8dab7b113efa724ce33e239d2b6464a69107ba5087ec9d6025f6306ddbda274980f944770769d72ff35ff2b6d56d7fc06320e2def33409de071
data/README.md CHANGED
@@ -1,4 +1,3 @@
1
- [![Stories in Ready](https://badge.waffle.io/clearsightstudio/ProMotion.png?label=ready&title=Ready)](https://waffle.io/clearsightstudio/ProMotion)
2
1
  # ProMotion
3
2
 
4
3
  [![Gem Version](https://img.shields.io/gem/v/ProMotion.svg?style=flat)](https://rubygems.org/gems/ProMotion)
@@ -6,6 +5,7 @@
6
5
  [![Code Climate](https://img.shields.io/codeclimate/github/clearsightstudio/ProMotion.svg?style=flat)](https://codeclimate.com/github/clearsightstudio/ProMotion)
7
6
  [![Dependency Status](https://img.shields.io/gemnasium/clearsightstudio/ProMotion.svg?style=flat)](https://gemnasium.com/clearsightstudio/ProMotion)
8
7
  [![omniref](https://img.shields.io/badge/omniref-docs-blue.svg?style=flat)](https://www.omniref.com/ruby/gems/ProMotion)
8
+ [![Stories in Ready](https://badge.waffle.io/clearsightstudio/ProMotion.png?label=ready&title=Ready)](https://waffle.io/clearsightstudio/ProMotion)
9
9
 
10
10
  ## iPhone Apps, Ruby-style
11
11
 
@@ -69,54 +69,57 @@ end
69
69
 
70
70
  |Screens|Navigation Bars|Tab Bars|
71
71
  |---|---|---|
72
- |![ProMotion Screen](https://f.cloud.github.com/assets/1479215/1534021/060aaaac-4c8f-11e3-903c-743e54252222.png)|![ProMotion Nav Bar](https://f.cloud.github.com/assets/1479215/1534077/db39aab6-4c8f-11e3-83f7-e03d52ac615d.png)|![ProMotion Tabs](https://f.cloud.github.com/assets/1479215/1534115/9f4c4cd8-4c90-11e3-9285-96ac253facda.png)|
72
+ |[![ProMotion Screen](https://f.cloud.github.com/assets/1479215/1534021/060aaaac-4c8f-11e3-903c-743e54252222.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20Screen/)|[![ProMotion Nav Bar](https://f.cloud.github.com/assets/1479215/1534077/db39aab6-4c8f-11e3-83f7-e03d52ac615d.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20Screen/#set_nav_bar_buttonside-args)|[![ProMotion Tabs](https://f.cloud.github.com/assets/1479215/1534115/9f4c4cd8-4c90-11e3-9285-96ac253facda.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20Tabs/)|
73
73
 
74
74
  |Table Screens|Grouped Tables|Searchable|Refreshable|
75
75
  |---|---|---|---|
76
- |![ProMotion TableScreen](https://f.cloud.github.com/assets/1479215/1534137/ed71e864-4c90-11e3-98aa-ed96049f5407.png)|![Grouped Table Screen](https://f.cloud.github.com/assets/1479215/1589973/61a48610-5281-11e3-85ac-abee99bf73ad.png)|![Searchable](https://f.cloud.github.com/assets/1479215/1534299/20cc05c6-4c93-11e3-92ca-9ee39c044457.png)|![Refreshable](https://f.cloud.github.com/assets/1479215/1534317/5a14ef28-4c93-11e3-8e9e-f8c08d8464f8.png)|
76
+ |[![ProMotion TableScreen](https://f.cloud.github.com/assets/1479215/1534137/ed71e864-4c90-11e3-98aa-ed96049f5407.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20TableScreen/)|[![Grouped Table Screen](https://f.cloud.github.com/assets/1479215/1589973/61a48610-5281-11e3-85ac-abee99bf73ad.png)](https://gist.github.com/jamonholmgren/382a6cf9963c5f0b2248)|[![Searchable](https://f.cloud.github.com/assets/1479215/1534299/20cc05c6-4c93-11e3-92ca-9ee39c044457.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20TableScreen/#searchableplaceholder-placeholder-text)|[![Refreshable](https://f.cloud.github.com/assets/1479215/1534317/5a14ef28-4c93-11e3-8e9e-f8c08d8464f8.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20TableScreen/#refreshableoptions)|
77
77
 
78
78
 
79
79
  |iPad SplitScreens|Map Screens|Web Screens|
80
80
  |---|---|---|
81
- |![ProMotion SplitScreens](https://f.cloud.github.com/assets/1479215/1534507/0edb8dd4-4c96-11e3-9896-d4583d0ed161.png)|![MapScreen](https://f.cloud.github.com/assets/1479215/1534628/f7dbf7e8-4c97-11e3-8817-4c2a58824771.png)|![ProMotion WebScreen](https://f.cloud.github.com/assets/1479215/1534631/ffe1b36a-4c97-11e3-8c8f-c7b14e26182d.png)|
81
+ |[![ProMotion SplitScreens](https://f.cloud.github.com/assets/1479215/1534507/0edb8dd4-4c96-11e3-9896-d4583d0ed161.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20SplitScreen/)|[![MapScreen](https://f.cloud.github.com/assets/1479215/1534628/f7dbf7e8-4c97-11e3-8817-4c2a58824771.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20MapScreen/)|[![ProMotion WebScreen](https://f.cloud.github.com/assets/1479215/1534631/ffe1b36a-4c97-11e3-8c8f-c7b14e26182d.png)](http://promotion.readthedocs.org/en/master/API%20Reference%20-%20ProMotion%20WebScreen/)|
82
82
 
83
83
  #### ...and much more.
84
84
 
85
85
  # Getting Started
86
86
 
87
- 1. Check out the [Getting Started Guide](https://github.com/clearsightstudio/ProMotion/wiki/Guide:-Getting-Started) in the wiki
87
+ 1. Check out the [Getting Started Guide](https://github.com/clearsightstudio/ProMotion/blob/master/docs/Guides/Guide%20-%20Getting%20Started.md)
88
88
  2. Watch the excellent [MotionInMotion screencast about ProMotion](https://motioninmotion.tv/screencasts/8) (very reasonably priced subscription required)
89
89
  3. Follow a tutorial: [Building an ESPN app using RubyMotion, ProMotion, and TDD](http://jamonholmgren.com/building-an-espn-app-using-rubymotion-promotion-and-tdd)
90
- 4. Read the updated and exhaustive [Wiki](https://github.com/clearsightstudio/ProMotion/wiki)
90
+ 4. Read the [Documentation](https://github.com/clearsightstudio/ProMotion/blob/master/docs)
91
91
 
92
92
  # Changelog
93
93
 
94
- ## Version 2.2.0
94
+ ## Version 2.3.0
95
95
 
96
96
  This release includes several new features and is backwards compatible with all 2.x releases.
97
97
 
98
- * PM::TableScreen: You can now set a custom table view header view ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/556))
99
- * PM::TableScreen refreshable: Refresh controls now show when programmatically initiating refresh ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/569))
100
- * PM::TableScreen: Added reorderable ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/569))
101
- * PM::TableScreen: Added auto height feature ([thanks Carlin Isaacson](https://github.com/clearsightstudio/ProMotion/pull/574))
102
- * 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))
103
- * PM::Screen: You can now choose a status bar style ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/563))
104
- * Added `on_load` and `on_styled` hooks for UIViews that implement those methods ([Jamon Holmgren](https://github.com/clearsightstudio/ProMotion/pull/567))
105
- * Fixed an issue where cell properties would be applied twice unnecessarily ([Jamon Holmgren](https://github.com/clearsightstudio/ProMotion/pull/573))
98
+ * PR #618 Allow search bar to be hidden initially
99
+ * PR #606 Adds capability for table_footer_view
100
+ * PR #602 Add image inset support for tab bar item
101
+ * PR #595 Feature/support module
102
+ * PR #582 Allow setting of multiple nav bar buttons instead of just one left an one right
103
+ * PR #581 Adds on_tab_selected
104
+ * PR #579 implemented nav_bar_button class method RE #272
105
+ * PR #565 Adds header_will_display method to PM::TableScreen
106
+ * PR #663 Adds `on_load` back to cell dequeue code
107
+ * PR #641 Custom search for PM::TableScreen
108
+ * PR #658 Fix cell height issue
106
109
 
107
110
  # Apps built on ProMotion
108
111
 
109
- [Apps built on ProMotion](https://github.com/clearsightstudio/ProMotion/wiki/Apps-built-on-ProMotion)
112
+ [Apps built on ProMotion](http://promotion.readthedocs.org/en/master/ProMotion%20Apps/)
110
113
 
111
- ##Your app
114
+ ## Your app
112
115
 
113
- Tweet [@jamonholmgren](https://twitter.com/jamonholmgren) if you built an app in ProMotion and want it included!
116
+ Open a pull request!
114
117
 
115
118
  # API Reference
116
119
 
117
120
  We've created a comprehensive and always updated wiki with code examples, usage examples, and API reference.
118
121
 
119
- ### [ProMotion API Reference](https://github.com/clearsightstudio/ProMotion/wiki)
122
+ ### [ProMotion Documentation](https://github.com/clearsightstudio/ProMotion/blob/master/docs)
120
123
 
121
124
  # Help
122
125
 
@@ -17,7 +17,11 @@ Motion::Project::App.setup do |app|
17
17
  "#{core_lib}/table/cell/table_view_cell_module.rb" => [ "#{core_lib}/styling/styling.rb" ],
18
18
  "#{core_lib}/delegate/delegate.rb" => [ "#{core_lib}/delegate/delegate_parent.rb" ],
19
19
  "#{core_lib}/delegate/delegate_parent.rb" => [ "#{core_lib}/delegate/delegate_module.rb" ],
20
- "#{core_lib}/delegate/delegate_module.rb" => [ "#{core_lib}/tabs/tabs.rb", "#{core_lib}/ipad/split_screen.rb" ],
20
+ "#{core_lib}/delegate/delegate_module.rb" => [
21
+ "#{core_lib}/support/support.rb",
22
+ "#{core_lib}/tabs/tabs.rb",
23
+ "#{core_lib}/ipad/split_screen.rb"
24
+ ],
21
25
  "#{core_lib}/screen/screen.rb" => [ "#{core_lib}/screen/screen_module.rb" ],
22
26
  "#{core_lib}/screen/screen_module.rb" => [ "#{core_lib}/screen/screen_navigation.rb" ],
23
27
  "#{core_lib}/table/data/table_data.rb" => [ "#{core_lib}/table/table.rb" ],
@@ -1,6 +1,8 @@
1
1
  module ProMotion
2
2
  class TabBarController < UITabBarController
3
3
 
4
+ attr_accessor :pm_tab_delegate
5
+
4
6
  def self.new(*screens)
5
7
  tab_bar_controller = alloc.init
6
8
 
@@ -15,6 +17,7 @@ module ProMotion
15
17
  end
16
18
 
17
19
  tab_bar_controller.viewControllers = view_controllers
20
+ tab_bar_controller.delegate = tab_bar_controller
18
21
  tab_bar_controller
19
22
  end
20
23
 
@@ -27,6 +30,9 @@ module ProMotion
27
30
 
28
31
  if selected_tab_vc
29
32
  self.selectedViewController = selected_tab_vc
33
+ on_tab_selected_try(selected_tab_vc)
34
+
35
+ selected_tab_vc
30
36
  else
31
37
  PM.logger.error "Unable to open tab #{tab.to_s} -- not found."
32
38
  nil
@@ -38,6 +44,9 @@ module ProMotion
38
44
  end
39
45
 
40
46
  # Cocoa touch methods below
47
+ def tabBarController(tbc, didSelectViewController: vc)
48
+ on_tab_selected_try(vc)
49
+ end
41
50
 
42
51
  def shouldAutorotate
43
52
  current_view_controller_try(:shouldAutorotate)
@@ -53,6 +62,12 @@ module ProMotion
53
62
 
54
63
  private
55
64
 
65
+ def on_tab_selected_try(vc)
66
+ if pm_tab_delegate && pm_tab_delegate.respond_to?(:weakref_alive?) && pm_tab_delegate.weakref_alive? && pm_tab_delegate.respond_to?("on_tab_selected:")
67
+ pm_tab_delegate.send(:on_tab_selected, vc)
68
+ end
69
+ end
70
+
56
71
  def current_view_controller
57
72
  selectedViewController || viewControllers.first
58
73
  end
@@ -1,5 +1,6 @@
1
1
  module ProMotion
2
2
  module DelegateModule
3
+ include ProMotion::Support
3
4
  include ProMotion::Tabs
4
5
  include ProMotion::SplitScreen if UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad
5
6
 
@@ -42,18 +43,6 @@ module ProMotion
42
43
  try :on_open_url, { url: url, source_app: source_app, annotation: annotation }
43
44
  end
44
45
 
45
- def app
46
- UIApplication.sharedApplication
47
- end
48
-
49
- def app_delegate
50
- self
51
- end
52
-
53
- def app_window
54
- window
55
- end
56
-
57
46
  def ui_window
58
47
  (defined?(Motion) && defined?(Motion::Xray) && defined?(Motion::Xray::XrayWindow)) ? Motion::Xray::XrayWindow : UIWindow
59
48
  end
@@ -83,10 +72,6 @@ module ProMotion
83
72
  self.class.send(:apply_status_bar)
84
73
  end
85
74
 
86
- def try(method, *args)
87
- send(method, *args) if respond_to?(method)
88
- end
89
-
90
75
  public
91
76
 
92
77
  module ClassMethods
@@ -18,8 +18,8 @@ module ProMotion
18
18
  end
19
19
 
20
20
  def set_nav_bar_button(side, args={})
21
- button = create_toolbar_button(args)
22
- button.setTintColor args[:tint_color] if args[:tint_color]
21
+ button = (args.is_a?(UIBarButtonItem)) ? args : create_toolbar_button(args)
22
+ button.setTintColor args[:tint_color] if args.is_a?(Hash) && args[:tint_color]
23
23
 
24
24
  self.navigationItem.leftBarButtonItem = button if side == :left
25
25
  self.navigationItem.rightBarButtonItem = button if side == :right
@@ -28,6 +28,13 @@ module ProMotion
28
28
  button
29
29
  end
30
30
 
31
+ def set_nav_bar_buttons(side, buttons=[])
32
+ buttons = buttons.map{ |b| b.is_a?(UIBarButtonItem) ? b : create_toolbar_button(b) }.reverse
33
+
34
+ self.navigationItem.setLeftBarButtonItems(buttons) if side == :left
35
+ self.navigationItem.setRightBarButtonItems(buttons) if side == :right
36
+ end
37
+
31
38
  # TODO: In PM 2.1+, entirely remove this deprecated method.
32
39
  def set_nav_bar_left_button(title, args={})
33
40
  PM.logger.deprecated "set_nav_bar_right_button and set_nav_bar_left_button have been removed. Use set_nav_bar_button :right/:left instead."
@@ -1,5 +1,6 @@
1
1
  module ProMotion
2
2
  module ScreenModule
3
+ include ProMotion::Support
3
4
  include ProMotion::ScreenNavigation
4
5
  include ProMotion::Styling
5
6
  include ProMotion::NavBarModule
@@ -13,6 +14,7 @@ module ProMotion
13
14
  resolve_title
14
15
  apply_properties(args)
15
16
  add_nav_bar(args) if args[:nav_bar]
17
+ add_nav_bar_buttons
16
18
  tab_bar_setup
17
19
  try :on_init
18
20
  try :screen_setup
@@ -46,6 +48,10 @@ module ProMotion
46
48
  end
47
49
  end
48
50
 
51
+ def add_nav_bar_buttons
52
+ set_nav_bar_button(self.class.get_nav_bar_button[:side], self.class.get_nav_bar_button) if self.class.get_nav_bar_button
53
+ end
54
+
49
55
  def status_bar_hidden(hidden)
50
56
  UIApplication.sharedApplication.setStatusBarHidden(hidden, withAnimation:self.class.status_bar_animation)
51
57
  end
@@ -166,10 +172,6 @@ module ProMotion
166
172
  return self.view_or_self.frame
167
173
  end
168
174
 
169
- def try(method, *args)
170
- send(method, *args) if respond_to?(method)
171
- end
172
-
173
175
  private
174
176
 
175
177
  def apply_properties(args)
@@ -229,6 +231,15 @@ module ProMotion
229
231
  def status_bar_animation
230
232
  @status_bar_animation || UIStatusBarAnimationSlide
231
233
  end
234
+
235
+ def nav_bar_button(side, args={})
236
+ @nav_bar_button_args = args
237
+ @nav_bar_button_args[:side] = side
238
+ end
239
+
240
+ def get_nav_bar_button
241
+ @nav_bar_button_args
242
+ end
232
243
  end
233
244
 
234
245
  def self.included(base)
@@ -1,5 +1,6 @@
1
1
  module ProMotion
2
2
  module ScreenNavigation
3
+ include ProMotion::Support
3
4
 
4
5
  def open_screen(screen, args = {})
5
6
  args = { animated: true }.merge(args)
@@ -32,14 +33,6 @@ module ProMotion
32
33
  open screen, args.merge({ modal: true })
33
34
  end
34
35
 
35
- def app
36
- UIApplication.sharedApplication
37
- end
38
-
39
- def app_delegate
40
- UIApplication.sharedApplication.delegate
41
- end
42
-
43
36
  def close_screen(args = {})
44
37
  args ||= {}
45
38
  args = { sender: args } unless args.is_a?(Hash)
@@ -0,0 +1,21 @@
1
+ module ProMotion
2
+ module Support
3
+
4
+ def app
5
+ UIApplication.sharedApplication
6
+ end
7
+
8
+ def app_delegate
9
+ UIApplication.sharedApplication.delegate
10
+ end
11
+
12
+ def app_window
13
+ UIApplication.sharedApplication.delegate.window
14
+ end
15
+
16
+ def try(method, *args)
17
+ send(method, *args) if respond_to?(method)
18
+ end
19
+
20
+ end
21
+ end
@@ -35,7 +35,7 @@ module ProMotion
35
35
  end
36
36
 
37
37
  def set_title
38
- set_attributed_text(self.textLabel, data_cell[:title])
38
+ set_attributed_text(self.textLabel, data_cell[:title]) if data_cell[:title]
39
39
  end
40
40
 
41
41
  def set_subtitle
@@ -2,16 +2,16 @@ module ProMotion
2
2
  class TableData
3
3
  include ProMotion::Table::Utils
4
4
 
5
- attr_accessor :data, :filtered_data, :search_string, :original_search_string, :filtered, :table_view
5
+ attr_accessor :data, :filtered_data, :search_string, :original_search_string, :filtered, :table_view, :search_params
6
6
 
7
- def initialize(data, table_view)
7
+ def initialize(data, table_view, search_action = nil)
8
+ @search_action ||= search_action
8
9
  self.data = data
9
10
  self.table_view = WeakRef.new(table_view)
10
11
  end
11
12
 
12
13
  def section(index)
13
- s = sections.at(index)
14
- s || { title: nil, cells: [] }
14
+ sections.at(index) || { cells: [] }
15
15
  end
16
16
 
17
17
  def sections
@@ -39,6 +39,10 @@ module ProMotion
39
39
  section(to.section)[:cells].insert(to.row, section(from.section)[:cells].delete_at(from.row))
40
40
  end
41
41
 
42
+ def default_search(cell, search_string)
43
+ cell[:searchable] != false && "#{cell[:title]}\n#{cell[:search_text]}".downcase.strip.include?(search_string.downcase.strip)
44
+ end
45
+
42
46
  def search(search_string)
43
47
  start_searching(search_string)
44
48
 
@@ -46,7 +50,11 @@ module ProMotion
46
50
  new_section = {}
47
51
 
48
52
  new_section[:cells] = section[:cells].map do |cell|
49
- cell[:searchable] != false && "#{cell[:title]}\n#{cell[:search_text]}".downcase.strip.include?(self.search_string) ? cell : nil
53
+ if @search_action
54
+ @search_action.call(cell, search_string)
55
+ else
56
+ self.default_search(cell, search_string)
57
+ end ? cell : nil
50
58
  end.compact
51
59
 
52
60
  if new_section[:cells] && new_section[:cells].length > 0
@@ -16,7 +16,7 @@ module ProMotion
16
16
  @table_search_display_controller.searchResultsDataSource = params[:data_source]
17
17
  @table_search_display_controller.searchResultsDelegate = params[:search_results_delegate]
18
18
 
19
- self.table_view.tableHeaderView = search_bar
19
+ self.tableView.tableHeaderView = search_bar
20
20
  end
21
21
  alias :makeSearchable :make_searchable
22
22
 
@@ -15,7 +15,7 @@ module ProMotion
15
15
 
16
16
  def screen_setup
17
17
  check_table_data
18
- set_up_header_view
18
+ set_up_header_footer_views
19
19
  set_up_searchable
20
20
  set_up_refreshable
21
21
  set_up_longpressable
@@ -27,16 +27,18 @@ module ProMotion
27
27
  end
28
28
 
29
29
  def promotion_table_data
30
- @promotion_table_data ||= TableData.new(table_data, table_view)
30
+ @promotion_table_data ||= TableData.new(table_data, table_view, setup_search_method)
31
31
  end
32
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."
33
+ def set_up_header_footer_views
34
+ [:header, :footer].each do |hf_view|
35
+ if self.respond_to?("table_#{hf_view}_view".to_sym)
36
+ view = self.send("table_#{hf_view}_view")
37
+ if view.is_a? UIView
38
+ self.tableView.send(camelize("set_table_#{hf_view}_view:"), view)
39
+ else
40
+ PM.logger.warn "Table #{hf_view} view must be a UIView."
41
+ end
40
42
  end
41
43
  end
42
44
  end
@@ -44,6 +46,23 @@ module ProMotion
44
46
  def set_up_searchable
45
47
  if self.class.respond_to?(:get_searchable) && self.class.get_searchable
46
48
  self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params)
49
+ if self.class.get_searchable_params[:hide_initially]
50
+ self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height)
51
+ end
52
+ end
53
+ end
54
+
55
+ def setup_search_method
56
+ params = self.class.get_searchable_params
57
+ if params.nil?
58
+ return nil
59
+ else
60
+ @search_method || begin
61
+ params = self.class.get_searchable_params
62
+ @search_action = params[:with] || params[:find_by] || params[:search_by] || params[:filter_by]
63
+ @search_action = method(@search_action) if @search_action.is_a?(Symbol) || @search_action.is_a?(String)
64
+ @search_action
65
+ end
47
66
  end
48
67
  end
49
68
 
@@ -136,9 +155,9 @@ module ProMotion
136
155
  new_cell.extend(PM::TableViewCellModule) unless new_cell.is_a?(PM::TableViewCellModule)
137
156
  new_cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
138
157
  new_cell.clipsToBounds = true # fix for changed default in 7.1
158
+ new_cell.send(:on_load) if new_cell.respond_to?(:on_load)
139
159
  new_cell
140
160
  end
141
-
142
161
  table_cell.setup(data_cell, self) if table_cell.respond_to?(:setup)
143
162
  table_cell.send(:on_reuse) if !new_cell && table_cell.respond_to?(:on_reuse)
144
163
  table_cell
@@ -167,42 +186,42 @@ module ProMotion
167
186
  end
168
187
 
169
188
  ########## Cocoa touch methods #################
170
- def numberOfSectionsInTableView(table_view)
189
+ def numberOfSectionsInTableView(_)
171
190
  self.promotion_table_data.sections.length
172
191
  end
173
192
 
174
193
  # Number of cells
175
- def tableView(table_view, numberOfRowsInSection: section)
194
+ def tableView(_, numberOfRowsInSection: section)
176
195
  self.promotion_table_data.section_length(section)
177
196
  end
178
197
 
179
- def tableView(table_view, titleForHeaderInSection: section)
198
+ def tableView(_, titleForHeaderInSection: section)
180
199
  section = promotion_table_data.section(section)
181
200
  section && section[:title]
182
201
  end
183
202
 
184
203
  # Set table_data_index if you want the right hand index column (jumplist)
185
- def sectionIndexTitlesForTableView(table_view)
204
+ def sectionIndexTitlesForTableView(_)
186
205
  return if self.promotion_table_data.filtered
187
206
  return self.table_data_index if self.respond_to?(:table_data_index)
188
207
  nil
189
208
  end
190
209
 
191
- def tableView(table_view, cellForRowAtIndexPath: index_path)
210
+ def tableView(_, cellForRowAtIndexPath: index_path)
192
211
  params = index_path_to_section_index(index_path: index_path)
193
212
  data_cell = self.promotion_table_data.cell(section: params[:section], index: params[:index])
194
213
  return UITableViewCell.alloc.init unless data_cell
195
214
  create_table_cell(data_cell)
196
215
  end
197
216
 
198
- def tableView(table_view, willDisplayCell: table_cell, forRowAtIndexPath: index_path)
217
+ def tableView(_, willDisplayCell: table_cell, forRowAtIndexPath: index_path)
199
218
  data_cell = self.promotion_table_data.cell(index_path: index_path)
200
219
  table_cell.send(:will_display) if table_cell.respond_to?(:will_display)
201
220
  table_cell.send(:restyle!) if table_cell.respond_to?(:restyle!) # Teacup compatibility
202
221
  end
203
222
 
204
- def tableView(table_view, heightForRowAtIndexPath: index_path)
205
- (self.promotion_table_data.cell(index_path: index_path)[:height] || table_view.rowHeight).to_f
223
+ def tableView(_, heightForRowAtIndexPath: index_path)
224
+ (self.promotion_table_data.cell(index_path: index_path)[:height] || tableView.rowHeight).to_f
206
225
  end
207
226
 
208
227
  def tableView(table_view, didSelectRowAtIndexPath: index_path)
@@ -211,18 +230,18 @@ module ProMotion
211
230
  trigger_action(data_cell[:action], data_cell[:arguments], index_path) if data_cell[:action]
212
231
  end
213
232
 
214
- def tableView(table_view, editingStyleForRowAtIndexPath: index_path)
233
+ def tableView(_, editingStyleForRowAtIndexPath: index_path)
215
234
  data_cell = self.promotion_table_data.cell(index_path: index_path, unfiltered: true)
216
235
  map_cell_editing_style(data_cell[:editing_style])
217
236
  end
218
237
 
219
- def tableView(table_view, commitEditingStyle: editing_style, forRowAtIndexPath: index_path)
238
+ def tableView(_, commitEditingStyle: editing_style, forRowAtIndexPath: index_path)
220
239
  if editing_style == UITableViewCellEditingStyleDelete
221
240
  delete_row(index_path)
222
241
  end
223
242
  end
224
243
 
225
- def tableView(tableView, canMoveRowAtIndexPath:index_path)
244
+ def tableView(_, canMoveRowAtIndexPath:index_path)
226
245
  data_cell = self.promotion_table_data.cell(index_path: index_path, unfiltered: true)
227
246
 
228
247
  if (!data_cell[:moveable].nil? || data_cell[:moveable].is_a?(Symbol)) && data_cell[:moveable] != false
@@ -232,7 +251,7 @@ module ProMotion
232
251
  end
233
252
  end
234
253
 
235
- def tableView(tableView, targetIndexPathForMoveFromRowAtIndexPath:source_index_path, toProposedIndexPath:proposed_destination_index_path)
254
+ def tableView(_, targetIndexPathForMoveFromRowAtIndexPath:source_index_path, toProposedIndexPath:proposed_destination_index_path)
236
255
  data_cell = self.promotion_table_data.cell(index_path: source_index_path, unfiltered: true)
237
256
 
238
257
  if data_cell[:moveable] == :section && source_index_path.section != proposed_destination_index_path.section
@@ -242,7 +261,7 @@ module ProMotion
242
261
  end
243
262
  end
244
263
 
245
- def tableView(tableView, moveRowAtIndexPath:from_index_path, toIndexPath:to_index_path)
264
+ def tableView(_, moveRowAtIndexPath:from_index_path, toIndexPath:to_index_path)
246
265
  self.promotion_table_data.move_cell(from_index_path, to_index_path)
247
266
 
248
267
  if self.respond_to?("on_cell_moved:")
@@ -259,11 +278,11 @@ module ProMotion
259
278
  end
260
279
  end
261
280
 
262
- def tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index)
281
+ def tableView(table_view, sectionForSectionIndexTitle: title, atIndex: index)
263
282
  return index unless ["{search}", UITableViewIndexSearch].include?(self.table_data_index[0])
264
283
 
265
284
  if index == 0
266
- tableView.scrollRectToVisible(CGRectMake(0.0, 0.0, 1.0, 1.0), animated: false)
285
+ table_view.scrollRectToVisible(CGRectMake(0.0, 0.0, 1.0, 1.0), animated: false)
267
286
  NSNotFound
268
287
  else
269
288
  index - 1
@@ -276,7 +295,7 @@ module ProMotion
276
295
  end
277
296
 
278
297
  # Section view methods
279
- def tableView(table_view, viewForHeaderInSection: index)
298
+ def tableView(_, viewForHeaderInSection: index)
280
299
  section = promotion_table_data.section(index)
281
300
  view = section[:title_view]
282
301
  view = section[:title_view].new if section[:title_view].respond_to?(:new)
@@ -284,7 +303,7 @@ module ProMotion
284
303
  view
285
304
  end
286
305
 
287
- def tableView(table_view, heightForHeaderInSection: index)
306
+ def tableView(_, heightForHeaderInSection: index)
288
307
  section = promotion_table_data.section(index)
289
308
  if section[:title_view] || section[:title].to_s.length > 0
290
309
  section[:title_view_height] || tableView.sectionHeaderHeight
@@ -293,6 +312,17 @@ module ProMotion
293
312
  end
294
313
  end
295
314
 
315
+ def tableView(_, willDisplayHeaderView:view, forSection:section)
316
+ action = :will_display_header
317
+ if respond_to?(action)
318
+ case self.method(action).arity
319
+ when 0 then self.send(action)
320
+ when 2 then self.send(action, view, section)
321
+ else self.send(action, view)
322
+ end
323
+ end
324
+ end
325
+
296
326
  protected
297
327
 
298
328
  def map_cell_editing_style(symbol)
@@ -4,6 +4,7 @@ module ProMotion
4
4
 
5
5
  def open_tab_bar(*screens)
6
6
  self.tab_bar = PM::TabBarController.new(screens)
7
+ self.tab_bar.pm_tab_delegate = WeakRef.new(self)
7
8
 
8
9
  delegate = self.respond_to?(:open_root_screen) ? self : UIApplication.sharedApplication.delegate
9
10
 
@@ -67,6 +68,7 @@ module ProMotion
67
68
  tab_bar_item = create_tab_bar_item_custom(title, tab[:item], current_tag) if tab[:item]
68
69
 
69
70
  tab_bar_item.badgeValue = tab[:badge_number].to_s unless tab[:badge_number].nil? || tab[:badge_number] <= 0
71
+ tab_bar_item.imageInsets = tab[:image_insets] if tab[:image_insets]
70
72
 
71
73
  tab_bar_item
72
74
  end
@@ -1,3 +1,3 @@
1
1
  module ProMotion
2
- VERSION = "2.2.2" unless defined?(ProMotion::VERSION)
2
+ VERSION = "2.3.0" unless defined?(ProMotion::VERSION)
3
3
  end
@@ -79,11 +79,6 @@ describe "PM::Delegate" do
79
79
 
80
80
  @subject.application(UIApplication.sharedApplication, openURL: url, sourceApplication:sourceApplication, annotation: annotation)
81
81
  end
82
-
83
- it "should have an awesome convenience method for UIApplication.sharedApplication" do
84
- @subject.app.should == UIApplication.sharedApplication
85
- end
86
-
87
82
  end
88
83
 
89
84
  # iOS 7 ONLY tests
@@ -88,6 +88,11 @@ describe "screen helpers" do
88
88
  end
89
89
 
90
90
  end
91
+
92
+ it "allows setting a nav_bar_button with a class method" do
93
+ screen = DetailScreen.new(nav_bar: true)
94
+ screen.navigationItem.rightBarButtonItem.class.should == UIBarButtonItem
95
+ end
91
96
  end
92
97
 
93
98
  describe "screen navigation" do
@@ -131,10 +131,6 @@ describe "screen properties" do
131
131
  @screen.shouldAutorotateToInterfaceOrientation(UIInterfaceOrientationMaskPortrait)
132
132
  end
133
133
 
134
- it "should have an awesome convenience method for UIApplication.sharedApplication" do
135
- @screen.app.should == UIApplication.sharedApplication
136
- end
137
-
138
134
  describe "iOS lifecycle methods" do
139
135
 
140
136
  it "-viewDidLoad" do
@@ -58,4 +58,49 @@ describe "Searchable table spec" do
58
58
  controller.searchDisplayController(controller, didLoadSearchResultsTableView: tableView)
59
59
  end
60
60
 
61
+ describe "custom search" do
62
+ before do
63
+ @stabby_controller = TableScreenStabbySearchable.new
64
+ @proc_controller = TableScreenSymbolSearchable.new
65
+ end
66
+
67
+ after do
68
+ @stabby_controller = nil
69
+ @proc_controller = nil
70
+ end
71
+
72
+ it "should allow searching for all the 'New' states using a custom search proc" do
73
+ @stabby_controller.searchDisplayController(@stabby_controller, shouldReloadTableForSearchString:"New Stabby")
74
+ @stabby_controller.tableView(@stabby_controller.tableView, numberOfRowsInSection:0).should == 4
75
+ rows = @stabby_controller.promotion_table_data.search("New stabby")
76
+ rows.first[:cells].length.should == 4
77
+ rows.first[:cells].each do |row|
78
+ # Starts with "New" and ends with "stabby"
79
+ row[:properties][:searched_title].should.match(/^New(.+)?stabby$/)
80
+ end
81
+ end
82
+
83
+ it "should allow searching for all the 'New' states using a symbol as a search proc" do
84
+ @proc_controller.searchDisplayController(@proc_controller, shouldReloadTableForSearchString:"New Symbol")
85
+ cell_count = @proc_controller.tableView(@proc_controller.tableView, numberOfRowsInSection:0)
86
+ cell_count.should == 4
87
+ rows = @proc_controller.promotion_table_data.search("New Symbol")
88
+ rows.first[:cells].length.should == 4
89
+ rows.first[:cells].each do |row|
90
+ # Starts with "New" and ends with "symbol"
91
+ row[:properties][:searched_title].should.match(/^New(.+)?symbol$/)
92
+ end
93
+ end
94
+
95
+ it "custom searches empty with stabby proc if there is no match" do
96
+ @stabby_controller.searchDisplayController(@stabby_controller, shouldReloadTableForSearchString:"Totally Bogus")
97
+ @stabby_controller.tableView(@stabby_controller.tableView, numberOfRowsInSection:0).should == 0
98
+ end
99
+
100
+ it "custom searches empty with symbol for proc if there is no match" do
101
+ @proc_controller.searchDisplayController(@proc_controller, shouldReloadTableForSearchString:"Totally Bogus")
102
+ @proc_controller.tableView(@proc_controller.tableView, numberOfRowsInSection:0).should == 0
103
+ end
104
+
105
+ end
61
106
  end
@@ -1,46 +1,53 @@
1
1
  describe "split screen functionality" do
2
2
 
3
- before do
4
- @app = TestDelegate.new
3
+ def master_screen
4
+ @master_screen ||= MasterScreen.new nav_bar: true
5
+ end
5
6
 
6
- @master_screen = MasterScreen.new nav_bar: true
7
- @detail_screen = DetailScreen.new # no nav_bar on this one
7
+ def detail_screen
8
+ @detail_screen ||= DetailScreen.new # no nav_bar on this one
9
+ end
8
10
 
9
- @split_screen = @app.open_split_screen @master_screen, @detail_screen
11
+ def app
12
+ @app ||= TestDelegate.new
13
+ end
14
+
15
+ def split_screen
16
+ @split_screen ||= app.open_split_screen master_screen, detail_screen
10
17
  end
11
18
 
12
19
  after do
13
- @split_screen.delegate = nil # dereference to avoid memory issue
20
+ split_screen.delegate = nil # dereference to avoid memory issue
14
21
  end
15
22
 
16
23
  it "should have created a split screen" do
17
- @split_screen.should != nil
18
- @split_screen.is_a?(UISplitViewController).should == true
24
+ split_screen.should != nil
25
+ split_screen.is_a?(UISplitViewController).should == true
19
26
  end
20
27
 
21
28
  it "should have two viewControllers" do
22
- @split_screen.viewControllers.length.should == 2
29
+ split_screen.viewControllers.length.should == 2
23
30
  end
24
31
 
25
32
  it "should set the root view to the UISplitScreenViewController" do
26
- @app.window.rootViewController.should == @split_screen
33
+ app.window.rootViewController.should == split_screen
27
34
  end
28
35
 
29
36
  it "should set the first viewController to MasterScreen" do
30
- @split_screen.master_screen.should == @master_screen
31
- @split_screen.viewControllers.first.should == (@master_screen.navigationController || @master_screen)
37
+ split_screen.master_screen.should == master_screen
38
+ split_screen.viewControllers.first.should == (master_screen.navigationController || master_screen)
32
39
  end
33
40
 
34
41
  it "should set the second viewController to DetailScreen" do
35
- @split_screen.detail_screen.should == @detail_screen
36
- @split_screen.viewControllers.last.should == (@detail_screen.navigationController || @detail_screen)
42
+ split_screen.detail_screen.should == detail_screen
43
+ split_screen.viewControllers.last.should == (detail_screen.navigationController || detail_screen)
37
44
  end
38
45
 
39
46
  it "should set the title on both screens" do
40
- @master_screen.class.title.should == "Master"
41
- @master_screen.title.should == "Master"
42
- @detail_screen.class.title.should == "Detail"
43
- @detail_screen.title.should == "Detail"
47
+ master_screen.class.title.should == "Master"
48
+ master_screen.title.should == "Master"
49
+ detail_screen.class.title.should == "Detail"
50
+ detail_screen.title.should == "Detail"
44
51
  end
45
52
  end
46
53
 
@@ -0,0 +1,45 @@
1
+ describe "PM::Support" do
2
+
3
+ before do
4
+ @app = TestDelegate.new
5
+ @screen = BasicScreen.new
6
+ @tab_screen = TabScreen.new
7
+ @table_screen = TestTableScreen.new
8
+ @web_screen = TestWebScreen.new
9
+ end
10
+
11
+ it "has a convenience method for UIApplication.sharedApplication" do
12
+ @app.app.should == UIApplication.sharedApplication
13
+ @screen.app.should == UIApplication.sharedApplication
14
+ @tab_screen.app.should == UIApplication.sharedApplication
15
+ @table_screen.app.should == UIApplication.sharedApplication
16
+ @web_screen.app.should == UIApplication.sharedApplication
17
+ end
18
+
19
+ it "has a convenience method for UIApplication.sharedApplication.delegate" do
20
+ @app.app_delegate.should == UIApplication.sharedApplication.delegate
21
+ @screen.app_delegate.should == UIApplication.sharedApplication.delegate
22
+ @tab_screen.app_delegate.should == UIApplication.sharedApplication.delegate
23
+ @table_screen.app_delegate.should == UIApplication.sharedApplication.delegate
24
+ @web_screen.app_delegate.should == UIApplication.sharedApplication.delegate
25
+ end
26
+
27
+ it "has a convenience method for UIApplication.sharedApplication.delegate.window" do
28
+ @app.app_window.should == UIApplication.sharedApplication.delegate.window
29
+ @screen.app_window.should == UIApplication.sharedApplication.delegate.window
30
+ @tab_screen.app_window.should == UIApplication.sharedApplication.delegate.window
31
+ @table_screen.app_window.should == UIApplication.sharedApplication.delegate.window
32
+ @web_screen.app_window.should == UIApplication.sharedApplication.delegate.window
33
+ end
34
+
35
+ it "has a try method" do
36
+ @app.try(:some_method).should == nil
37
+ @screen.try(:some_method).should == nil
38
+ @tab_screen.try(:some_method).should == nil
39
+ @table_screen.try(:some_method).should == nil
40
+ @web_screen.try(:some_method).should == nil
41
+ end
42
+
43
+ end
44
+
45
+
@@ -19,6 +19,17 @@ describe "PM::Tabs" do
19
19
  app.window.rootViewController.should.be.kind_of UITabBarController
20
20
  end
21
21
 
22
+ it "should set the the pm_tab_delegate to the opener" do
23
+ tab_bar.pm_tab_delegate.should.equal(app)
24
+ tab_bar.delegate.should.equal(tab_bar)
25
+ end
26
+
27
+ it "should call on_tab_selected when a tab is selected" do
28
+ tab_bar.pm_tab_delegate.called_on_tab_selected = false
29
+ @screen1.open_tab "Screen 2"
30
+ tab_bar.pm_tab_delegate.called_on_tab_selected.should.be.true
31
+ end
32
+
22
33
  it "should have four tabs" do
23
34
  tab_bar.viewControllers.length.should == 4
24
35
  end
@@ -25,6 +25,10 @@ describe "tab bar functionality" do
25
25
  @tab_bar.tabBar.items.first.title.should == "Tab Item"
26
26
  end
27
27
 
28
+ it "should allow setting image insets" do
29
+ @tab_bar.tabBar.items.first.imageInsets.should == UIEdgeInsetsMake(5,5,5,5)
30
+ end
31
+
28
32
  it "should have set the others to their respective titles" do
29
33
  @tab_bar.tabBar.items[1].title.should == "Basic"
30
34
  @tab_bar.tabBar.items[2].title.should == "Home"
@@ -175,6 +175,10 @@ describe "PM::Table module" do
175
175
  @subject.tableView.tableHeaderView.class.should == UIImageView
176
176
  end
177
177
 
178
+ it "should have a footer view" do
179
+ @subject.tableView.tableFooterView.class.should == UIView
180
+ end
181
+
178
182
  describe("section with custom title_view") do
179
183
 
180
184
  it "should use the correct class for section view" do
@@ -196,4 +200,19 @@ describe "PM::Table module" do
196
200
  end
197
201
  end
198
202
 
203
+ describe "header view modifications" do
204
+
205
+ it "should call will_display_header" do
206
+ header = @subject.tableView(@subject.table_view, viewForHeaderInSection: 4)
207
+ @subject.tableView(@subject.table_view, willDisplayHeaderView:header, forSection:1)
208
+
209
+ @subject.got_will_display_header.tap do |h|
210
+ h.nil?.should == false
211
+ h[:section].should == 1
212
+ h[:view].should == header
213
+ end
214
+ end
215
+
216
+ end
217
+
199
218
  end
@@ -80,6 +80,19 @@ describe "table screens" do
80
80
  @screen.tableView.tableHeaderView.should.be.kind_of UISearchBar
81
81
  end
82
82
 
83
+ it "should not hide the search bar initally by default" do
84
+ @screen.tableView.contentOffset.should == CGPointMake(0,0)
85
+ end
86
+
87
+ it "should allow hiding the search bar initally" do
88
+ class HiddenSearchScreen < TableScreenSearchable
89
+ searchable hide_initially: true
90
+ end
91
+ screen = HiddenSearchScreen.new
92
+ screen.on_load
93
+ screen.tableView.contentOffset.should == CGPointMake(0,screen.searchDisplayController.searchBar.frame.size.height)
94
+ end
95
+
83
96
  end
84
97
 
85
98
  describe "refresh functionality" do
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.2.2
4
+ version: 2.3.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: 2015-04-02 00:00:00.000000000 Z
13
+ date: 2015-04-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: methadone
@@ -116,6 +116,7 @@ files:
116
116
  - lib/ProMotion/stubs/dummy_image_view.rb
117
117
  - lib/ProMotion/stubs/dummy_view.rb
118
118
  - lib/ProMotion/styling/styling.rb
119
+ - lib/ProMotion/support/support.rb
119
120
  - lib/ProMotion/table/cell/table_view_cell_module.rb
120
121
  - lib/ProMotion/table/data/table_data.rb
121
122
  - lib/ProMotion/table/extensions/indexable.rb
@@ -151,6 +152,7 @@ files:
151
152
  - spec/unit/split_screen_in_tab_bar_spec.rb
152
153
  - spec/unit/split_screen_open_screen_spec.rb
153
154
  - spec/unit/split_screen_spec.rb
155
+ - spec/unit/support_spec.rb
154
156
  - spec/unit/tab_bar_spec.rb
155
157
  - spec/unit/tab_spec.rb
156
158
  - spec/unit/tables/table_indexable_spec.rb
@@ -210,6 +212,7 @@ test_files:
210
212
  - spec/unit/split_screen_in_tab_bar_spec.rb
211
213
  - spec/unit/split_screen_open_screen_spec.rb
212
214
  - spec/unit/split_screen_spec.rb
215
+ - spec/unit/support_spec.rb
213
216
  - spec/unit/tab_bar_spec.rb
214
217
  - spec/unit/tab_spec.rb
215
218
  - spec/unit/tables/table_indexable_spec.rb