ProMotion 2.2.2 → 2.3.0

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.
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