ProMotion 1.0.4 → 1.1.0.rc1

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/ProMotion.gemspec +3 -2
  3. data/README.md +10 -7
  4. data/app/screens/basic_screen.rb +12 -0
  5. data/bin/promotion +45 -0
  6. data/lib/ProMotion/cocoatouch/table_view_controller.rb +2 -2
  7. data/lib/ProMotion/cocoatouch/view_controller.rb +2 -2
  8. data/lib/ProMotion/containers/split_screen.rb +6 -1
  9. data/lib/ProMotion/containers/tabs.rb +12 -1
  10. data/lib/ProMotion/delegate/delegate_module.rb +16 -2
  11. data/lib/ProMotion/delegate/delegate_notifications.rb +7 -7
  12. data/lib/ProMotion/map/map_screen_annotation.rb +10 -1
  13. data/lib/ProMotion/map/map_screen_module.rb +8 -3
  14. data/lib/ProMotion/pro_motion.rb +1 -1
  15. data/lib/ProMotion/screen/screen_module.rb +35 -16
  16. data/lib/ProMotion/screen/screen_navigation.rb +11 -13
  17. data/lib/ProMotion/table/extensions/indexable.rb +2 -2
  18. data/lib/ProMotion/table/extensions/searchable.rb +4 -3
  19. data/lib/ProMotion/table/grouped_table.rb +7 -2
  20. data/lib/ProMotion/table/table.rb +54 -47
  21. data/lib/ProMotion/thirdparty/formotion_screen.rb +5 -3
  22. data/lib/ProMotion/version.rb +1 -1
  23. data/lib/ProMotion/view/styling.rb +33 -20
  24. data/resources/test.png +0 -0
  25. data/spec/functional/func_map_screen_spec.rb +60 -3
  26. data/spec/functional/func_screen_spec.rb +29 -6
  27. data/spec/functional/func_searchable_table_spec.rb +13 -1
  28. data/spec/functional/func_split_screen_spec.rb +8 -0
  29. data/spec/functional/func_table_screen_spec.rb +28 -23
  30. data/spec/functional/func_web_screen_spec.rb +1 -1
  31. data/spec/helpers/custom_title_view.rb +4 -0
  32. data/spec/helpers/home_screen.rb +6 -0
  33. data/spec/helpers/table_screen.rb +23 -27
  34. data/spec/helpers/table_screen_formotion.rb +5 -0
  35. data/spec/helpers/table_screen_searchable.rb +10 -0
  36. data/spec/helpers/test_delegate_colors.rb +17 -0
  37. data/spec/helpers/test_helper.rb +5 -0
  38. data/spec/unit/delegate_spec.rb +79 -1
  39. data/spec/unit/map_spec.rb +22 -0
  40. data/spec/unit/screen_helpers_spec.rb +44 -35
  41. data/spec/unit/screen_spec.rb +45 -6
  42. data/spec/unit/split_screen_open_screen_spec.rb +1 -1
  43. data/spec/unit/tables/formotion_screen_spec.rb +6 -0
  44. data/spec/unit/tables/table_module_spec.rb +28 -2
  45. data/spec/unit/tables/table_view_cell_spec.rb +5 -4
  46. data/spec/unit/view_helper_spec.rb +21 -10
  47. metadata +28 -6
  48. data/resources/test.jpeg +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 602b5c98e83522111d9b53bddef00fc265d7e190
4
- data.tar.gz: 22427e49f5b04332fceb59b721b014a380402151
3
+ metadata.gz: 2a8dbafa82311f57f50c6d99c19cecae98f63b67
4
+ data.tar.gz: fdd29443346a2450e79dc914431a621f1a037d45
5
5
  SHA512:
6
- metadata.gz: 8ef6b7a74482a7695a76b7745586cc79bb28974a2ad77cdd44a52b6d38208baf27ab49649fdc5e79efebd2febafcf444f61935303eb9b4a3a59b031a0639d2db
7
- data.tar.gz: f9766e5e2568e7ca49fd21032de3a0e999541d4dff0abe8f38490a18ed0dfd39470563da0ac6dcffc12259c2baaeb09da9457760479e91b57e6e16a667fb3eb9
6
+ metadata.gz: 25ed34fdb3a9f089113559a1383baedf0b4de0cbf2c1472aadde51e7d920111b7e0aba7702bc061583b195e3020569cef2032ddf56ef87c2d6181f8466510ee1
7
+ data.tar.gz: 5085d8e82fadf7747305d270f669ab72db9301e139031a7851df8b892f53616c24fc4443b87b9cddae8930bfcad4041072e683faddb610420c7bda05d4f30904
@@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
15
15
  gem.license = 'MIT'
16
16
 
17
17
  gem.files = `git ls-files`.split($\)
18
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.executables << "promotion"
19
+ gem.test_files = gem.files.grep(%r{^(spec)/})
20
20
  gem.name = "ProMotion"
21
21
  gem.require_paths = ["lib"]
22
22
  gem.version = ProMotion::VERSION
@@ -26,4 +26,5 @@ Gem::Specification.new do |gem|
26
26
  gem.add_development_dependency("motion-redgreen")
27
27
  gem.add_development_dependency("formotion")
28
28
  gem.add_development_dependency("rake")
29
+ gem.add_dependency("methadone")
29
30
  end
data/README.md CHANGED
@@ -1,12 +1,15 @@
1
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
- ## A new way to easily build RubyMotion apps.
3
+ ## iPhone Apps, Ruby-style
4
4
 
5
5
  ProMotion is a RubyMotion gem that makes iOS development more like Ruby and less like Objective-C.
6
6
  It introduces a clean, Ruby-style syntax for building screens that is easy to learn and remember and
7
7
  abstracts a ton of boilerplate UIViewController, UINavigationController, and other iOS code into a
8
8
  simple, Ruby-like DSL.
9
9
 
10
+ Watch the [September Motion Meetup](http://www.youtube.com/watch?v=rf7h-3AiMRQ) where Gant Laborde
11
+ interviews Jamon Holmgren about ProMotion!
12
+
10
13
  ```ruby
11
14
  class AppDelegate < PM::Delegate
12
15
  def on_load(app, options)
@@ -16,7 +19,7 @@ end
16
19
 
17
20
  class RootScreen < PM::Screen
18
21
  title "Root Screen"
19
-
22
+
20
23
  def push_new_screen
21
24
  open NewScreen
22
25
  end
@@ -24,7 +27,7 @@ end
24
27
 
25
28
  class NewScreen < PM::TableScreen
26
29
  title "Table Screen"
27
-
30
+
28
31
  def table_data
29
32
  [{
30
33
  cells: [
@@ -40,16 +43,16 @@ end
40
43
 
41
44
  |Screens|Navigation Bars|Tab Bars|
42
45
  |---|---|---|
43
- |![ProMotion Screen](https://f.cloud.github.com/assets/1479215/751058/486b6e1e-e4e7-11e2-9d1f-d9380a58f643.png)|![ProMotion Nav Bar](https://f.cloud.github.com/assets/1479215/751076/e4762858-e4e7-11e2-8442-ac7c9ad142e6.png)|![ProMotion Tabs](https://f.cloud.github.com/assets/1479215/751128/76ebe320-e4e9-11e2-86ee-d81c4c1e92f2.png)|
46
+ |![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)|
44
47
 
45
48
  |Table Screens|Grouped Tables|Searchable|Refreshable|
46
49
  |---|---|---|---|
47
- |![ProMotion TableScreen](https://f.cloud.github.com/assets/1479215/751067/8fe7631a-e4e7-11e2-84f1-6ae50ac4f8e8.png)|![ProMotion Grouped Table Screens](https://f.cloud.github.com/assets/1479215/751162/a805b9da-e4ea-11e2-9c39-0c65f8a8de77.png)|![Searchable](https://f.cloud.github.com/assets/1479215/707490/ba750216-de1d-11e2-9594-0880b12f8ffe.png)|![Refreshable](https://f.cloud.github.com/assets/139261/472574/af268e52-b735-11e2-8b9b-a9245b421715.gif)|
50
+ |![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)|
48
51
 
49
52
 
50
53
  |iPad SplitScreens|Map Screens|Web Screens|
51
54
  |---|---|---|
52
- |![ProMotion SplitScreens](https://f.cloud.github.com/assets/1479215/751188/13c3a7c6-e4ec-11e2-8c87-a94e0c07702b.png)|![MapScreen](https://f.cloud.github.com/assets/1479215/751217/dab20958-e4ed-11e2-9b3e-b42c0199d9e7.png)|![ProMotion WebScreen](https://f.cloud.github.com/assets/1479215/751235/b6fe91ba-e4ee-11e2-8707-c74c7f833de3.png)|
55
+ |![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)|
53
56
 
54
57
  #### ...and much more.
55
58
 
@@ -136,7 +139,7 @@ incorporated.
136
139
  3. Code
137
140
  4. Update or create new specs ** NOTE: your PR is far more likely to be merged if you include comprehensive tests! **
138
141
  5. Make sure tests are passing by running `rake spec` *(you can run functional and unit specs separately with `rake spec:functional` and `rake spec:unit`)*
139
- 6. Submit pull request
142
+ 6. Submit pull request to `edge` (for new features) or `master` (for bugfixes)
140
143
  7. Make a million little nitpicky changes that @jamonholmgren wants
141
144
  8. Merged, then fame, adoration, kudos everywhere
142
145
 
@@ -1,3 +1,15 @@
1
1
  class BasicScreen < PM::Screen
2
2
  title "Basic"
3
+
4
+ attr_reader :animation_ts
5
+
6
+ def will_appear
7
+ @will_appear_ts = NSDate.date
8
+ end
9
+
10
+ def on_appear
11
+ @on_appear_ts = NSDate.date
12
+ @animation_ts = @on_appear_ts - @will_appear_ts
13
+ end
14
+
3
15
  end
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'methadone'
5
+ require 'ProMotion/version'
6
+
7
+ class App
8
+ include Methadone::Main
9
+ include Methadone::CLILogging
10
+ include Methadone::SH
11
+
12
+ main do |command, opt|
13
+ case command.to_sym
14
+ when :new then create(opt)
15
+ when :help then show_help
16
+ else show_help
17
+ end
18
+
19
+ 0 # Good!
20
+ end
21
+
22
+ def self.show_help
23
+ info "promotion - Command line tools for ProMotion."
24
+ info "By Jamon Holmgren"
25
+ info ""
26
+ info "Commands:"
27
+ info " new <appname>"
28
+ info " Creates a new ProMotion app from a template."
29
+ end
30
+
31
+ def self.create(name)
32
+ return puts "Usage: promotion new <appname>" unless name.to_s.length > 0
33
+ info "Creating new ProMotion iOS app #{name}"
34
+ sh "motion create --template=git@github.com:jamonholmgren/promotion-template.git #{name}"
35
+ end
36
+
37
+ description "Command line for ProMotion."
38
+
39
+ arg :command
40
+ arg :opt, :optional
41
+
42
+ version ProMotion::VERSION
43
+
44
+ go!
45
+ end
@@ -1,7 +1,7 @@
1
1
  module ProMotion
2
2
  class TableViewController < UITableViewController
3
3
  def self.new(args = {})
4
- s = self.alloc.initWithNibName(nil, bundle:nil)
4
+ s = self.alloc.initWithStyle(table_style)
5
5
  s.on_create(args) if s.respond_to?(:on_create)
6
6
  s
7
7
  end
@@ -52,4 +52,4 @@ module ProMotion
52
52
  self.on_rotate
53
53
  end
54
54
  end
55
- end
55
+ end
@@ -1,11 +1,11 @@
1
1
  module ProMotion
2
2
  class ViewController < UIViewController
3
3
  def self.new(args = {})
4
- s = self.alloc.initWithNibName(nil, bundle:nil)
4
+ s = self.alloc.initWithNibName(args[:nib_name] || nil, bundle:args[:bundle] || nil)
5
5
  s.on_create(args) if s.respond_to?(:on_create)
6
6
  s
7
7
  end
8
-
8
+
9
9
  def loadView
10
10
  super
11
11
  self.send(:on_load) if self.respond_to?(:on_load)
@@ -21,6 +21,11 @@ module ProMotion
21
21
  if args.has_key?(:icon) or args.has_key?(:title)
22
22
  split.tabBarItem = create_tab_bar_item(args)
23
23
  end
24
+
25
+ if args.has_key?(:button_title)
26
+ @button_title = args[:button_title]
27
+ end
28
+
24
29
  split
25
30
  end
26
31
 
@@ -33,7 +38,7 @@ module ProMotion
33
38
  # UISplitViewControllerDelegate methods
34
39
 
35
40
  def splitViewController(svc, willHideViewController: vc, withBarButtonItem: button, forPopoverController: pc)
36
- button.title = vc.title
41
+ button.title = @button_title || vc.title
37
42
  svc.detail_screen.navigationItem.leftBarButtonItem = button;
38
43
  end
39
44
 
@@ -38,8 +38,19 @@ module ProMotion
38
38
  def create_tab_bar_icon_custom(title, icon_image, tag)
39
39
  if icon_image.is_a?(String)
40
40
  icon_image = UIImage.imageNamed(icon_image)
41
+ elsif icon_image.is_a?(Hash)
42
+ icon_selected = icon_image[:selected]
43
+ icon_unselected = icon_image[:unselected]
44
+ icon_image = nil
41
45
  end
42
- return UITabBarItem.alloc.initWithTitle(title, image:icon_image, tag:tag)
46
+
47
+ item = UITabBarItem.alloc.initWithTitle(title, image:icon_image, tag:tag)
48
+
49
+ if icon_selected || icon_unselected
50
+ item.setFinishedSelectedImage(icon_selected, withFinishedUnselectedImage: icon_unselected)
51
+ end
52
+
53
+ return item
43
54
  end
44
55
 
45
56
  def create_tab_bar_item(tab={})
@@ -1,8 +1,7 @@
1
1
  module ProMotion
2
2
  module DelegateModule
3
-
4
3
  include ProMotion::Tabs
5
- include ProMotion::SplitScreen if NSBundle.mainBundle.infoDictionary["UIDeviceFamily"].include?("2") # Only with iPad
4
+ include ProMotion::SplitScreen if UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad
6
5
  include ProMotion::DelegateNotifications
7
6
 
8
7
  attr_accessor :window, :aps_notification, :home_screen
@@ -38,6 +37,10 @@ module ProMotion
38
37
  on_unload if respond_to?(:on_unload)
39
38
  end
40
39
 
40
+ def application(application, openURL: url, sourceApplication:source_app, annotation: annotation)
41
+ on_open_url({ url: url, source_app: source_app, annotation: annotation }) if respond_to?(:on_open_url)
42
+ end
43
+
41
44
  def app_delegate
42
45
  self
43
46
  end
@@ -58,6 +61,7 @@ module ProMotion
58
61
 
59
62
  self.window ||= self.ui_window.alloc.initWithFrame(UIScreen.mainScreen.bounds)
60
63
  self.window.rootViewController = (screen.navigationController || screen)
64
+ self.window.tintColor = self.class.send(:get_tint_color) if self.window.respond_to?("tintColor=")
61
65
  self.window.makeKeyAndVisible
62
66
 
63
67
  screen
@@ -95,6 +99,16 @@ module ProMotion
95
99
  }[opt] || UIStatusBarAnimationNone
96
100
  end
97
101
 
102
+ def tint_color(c)
103
+ @tint_color = c
104
+ end
105
+ def tint_color=(c)
106
+ @tint_color = c
107
+ end
108
+ def get_tint_color
109
+ @tint_color || nil
110
+ end
111
+
98
112
  end
99
113
 
100
114
  def self.included(base)
@@ -27,10 +27,10 @@ module ProMotion
27
27
  mask = UIApplication.sharedApplication.enabledRemoteNotificationTypes
28
28
  types = []
29
29
 
30
- types << :badge if mask & UIRemoteNotificationTypeBadge
31
- types << :sound if mask & UIRemoteNotificationTypeSound
32
- types << :alert if mask & UIRemoteNotificationTypeAlert
33
- types << :newsstand if mask & UIRemoteNotificationTypeNewsstandContentAvailability
30
+ types << :badge if mask & UIRemoteNotificationTypeBadge > 0
31
+ types << :sound if mask & UIRemoteNotificationTypeSound > 0
32
+ types << :alert if mask & UIRemoteNotificationTypeAlert > 0
33
+ types << :newsstand if mask & UIRemoteNotificationTypeNewsstandContentAvailability > 0
34
34
 
35
35
  types
36
36
  end
@@ -51,11 +51,11 @@ module ProMotion
51
51
  end
52
52
 
53
53
  def application(application, didReceiveRemoteNotification:notification)
54
- received_push_notification(notification, false)
54
+ received_push_notification(notification, application.applicationState != UIApplicationStateActive)
55
55
  end
56
-
56
+
57
57
  protected
58
-
58
+
59
59
  def map_notification_symbol(symbol)
60
60
  {
61
61
  none: UIRemoteNotificationTypeNone,
@@ -17,7 +17,7 @@ module ProMotion
17
17
  @params = {
18
18
  title: "Title",
19
19
  pin_color: MKPinAnnotationColorRed,
20
- identifier: "Annotation-#{@params[:pin_color]}",
20
+ identifier: "Annotation-#{@params[:pin_color] || @params[:image]}",
21
21
  show_callout: true,
22
22
  animates_drop: false
23
23
  }.merge(@params)
@@ -52,5 +52,14 @@ module ProMotion
52
52
  @params
53
53
  end
54
54
 
55
+ def method_missing(meth, *args)
56
+ if @params[meth.to_sym]
57
+ @params[meth.to_sym]
58
+ else
59
+ PM.logger.warn "The annotation parameter \"#{meth}\" does not exist on this pin."
60
+ nil
61
+ end
62
+ end
63
+
55
64
  end
56
65
  end
@@ -100,10 +100,15 @@ module ProMotion
100
100
  view.annotation = annotation
101
101
  else
102
102
  #Set the pin properties
103
- view = MKPinAnnotationView.alloc.initWithAnnotation(annotation, reuseIdentifier:identifier)
103
+ if annotation.annotation_params[:image]
104
+ view = MKAnnotationView.alloc.initWithAnnotation(annotation, reuseIdentifier:identifier)
105
+ view.image = annotation.annotation_params[:image]
106
+ else
107
+ view = MKPinAnnotationView.alloc.initWithAnnotation(annotation, reuseIdentifier:identifier)
108
+ view.animatesDrop = annotation.annotation_params[:animates_drop]
109
+ view.pinColor = annotation.annotation_params[:pin_color]
110
+ end
104
111
  view.canShowCallout = annotation.annotation_params[:show_callout]
105
- view.animatesDrop = annotation.annotation_params[:animates_drop]
106
- view.pinColor = annotation.annotation_params[:pin_color]
107
112
  end
108
113
  view
109
114
  end
@@ -1,3 +1,3 @@
1
1
  module ProMotion
2
2
  end
3
- ::PM = ProMotion unless defined?(::PM)
3
+ ::PM = ProMotion unless defined?(::PM)
@@ -33,20 +33,23 @@ module ProMotion
33
33
  end
34
34
 
35
35
  def nav_bar?
36
- !!self.navigation_controller
36
+ !!self.navigationController
37
37
  end
38
38
 
39
39
  def navigation_controller
40
- @navigation_controller ||= self.navigationController
40
+ self.navigationController
41
41
  end
42
42
 
43
- def navigation_controller=(val)
44
- @navigation_controller = val
45
- val
43
+ def navigation_controller=(nav)
44
+ @navigationController = nav
45
+ end
46
+
47
+ def navigationController=(nav)
48
+ @navigationController = nav
46
49
  end
47
50
 
48
51
  def add_nav_bar(args = {})
49
- self.navigation_controller ||= begin
52
+ self.navigationController ||= begin
50
53
  self.first_screen = true if self.respond_to?(:first_screen=)
51
54
  nav = NavigationController.alloc.initWithRootViewController(self)
52
55
  nav.setModalTransitionStyle(args[:transition_style]) if args[:transition_style]
@@ -66,22 +69,36 @@ module ProMotion
66
69
  end
67
70
 
68
71
  def set_nav_bar_button(side, args={})
72
+ button = create_toolbar_button(args)
73
+
74
+ self.navigationItem.leftBarButtonItem = button if side == :left
75
+ self.navigationItem.rightBarButtonItem = button if side == :right
76
+ self.navigationItem.backBarButtonItem = button if side == :back
77
+
78
+ button
79
+ end
80
+
81
+ def create_toolbar_button(args = {})
69
82
  args[:style] = map_bar_button_item_style(args[:style])
70
83
  args[:target] ||= self
71
84
  args[:action] ||= nil
85
+ args[:custom_view] = args[:custom_view] if args[:custom_view]
72
86
  args[:system_item] ||= args[:system_icon] # backwards compatibility
73
87
  args[:system_item] = map_bar_button_system_item(args[:system_item]) if args[:system_item] && args[:system_item].is_a?(Symbol)
74
-
75
- button_type = args[:image] || args[:button] || args[:system_item] || args[:title] || "Button"
76
88
 
77
- button = bar_button_item button_type, args
89
+ button_type = args[:image] || args[:button] || args[:system_item] || args[:custom_view] || args[:title] || "Button"
78
90
 
79
- self.navigationItem.leftBarButtonItem = button if side == :left
80
- self.navigationItem.rightBarButtonItem = button if side == :right
91
+ bar_button_item button_type, args
92
+ end
81
93
 
82
- button
94
+ def set_toolbar_items(buttons = [], animated = true)
95
+ buttons = Array(buttons)
96
+ self.toolbarItems = buttons.map{|b| b.is_a?(UIBarButtonItem) ? b : create_toolbar_button(b) }
97
+ navigation_controller.setToolbarHidden(false, animated:animated)
83
98
  end
84
-
99
+ alias_method :set_toolbar_buttons, :set_toolbar_items
100
+ alias_method :set_toolbar_button, :set_toolbar_items
101
+
85
102
  # TODO: Make this better. Not able to do image: "logo", for example.
86
103
  def bar_button_item(button_type, args)
87
104
  case button_type
@@ -92,7 +109,9 @@ module ProMotion
92
109
  when String
93
110
  UIBarButtonItem.alloc.initWithTitle(button_type, style: args[:style], target: args[:target], action: args[:action])
94
111
  else
95
- if args[:system_item]
112
+ if args[:custom_view]
113
+ UIBarButtonItem.alloc.initWithCustomView(args[:custom_view])
114
+ elsif args[:system_item]
96
115
  UIBarButtonItem.alloc.initWithBarButtonSystemItem(args[:system_item], target: args[:target], action: args[:action])
97
116
  else
98
117
  PM.logger.error("Please supply a title string, a UIImage or :system.")
@@ -208,7 +227,7 @@ module ProMotion
208
227
  def frame
209
228
  return self.view_or_self.frame
210
229
  end
211
-
230
+
212
231
  def map_bar_button_item_style(symbol)
213
232
  symbol = {
214
233
  plain: UIBarButtonItemStylePlain,
@@ -217,7 +236,7 @@ module ProMotion
217
236
  }[symbol] if symbol.is_a?(Symbol)
218
237
  symbol || UIBarButtonItemStyleBordered
219
238
  end
220
-
239
+
221
240
  def map_bar_button_system_item(symbol)
222
241
  {
223
242
  done: UIBarButtonSystemItemDone,