sugarcube 2.2.0 → 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: 9ea660a3118fd4a7088293e17717ce63bcd5eace
4
- data.tar.gz: 125596accb09c632e465ad0c6210ee85f277482f
3
+ metadata.gz: 4927c830c7506b761237ac68832cd66de069053c
4
+ data.tar.gz: e8c5a0ce9349cda4d726d8867396a7f58f33b588
5
5
  SHA512:
6
- metadata.gz: deb47f000d638c607df1cad4f716ba5d409c33aa79e9e431db534bf0a8dcc7bcf2ec16d05065ce4db09614a873a571d9dbbd16ed47f973022abcb6cb77e9f4a8
7
- data.tar.gz: 70c071626397a53e0f2f5635c0add025c93731c3b2a815fb460c4b6d6091ec5e32e4cfad890f32369860a6e3859c98cc717f72e16e49923fe2c602fc9e8c21db
6
+ metadata.gz: a90054a85c93abbc71842479b0cdc19410d23e73500ab5862b20454e8f1e9c737d36286750272167e4f8894ae0bbb4c80ec5ec0b14e350a77403b576e15de4a8
7
+ data.tar.gz: 883da51ede064c5d663aef73ff023473971ee8ab478183b2f268b8a96bafda318c114ff23fb7b9f8412267a76b7da61678e4f7205c6b281fd224a2c91249b815
data/README.md CHANGED
@@ -745,6 +745,34 @@ UIActionSheet.alert('Well, how bout it?',
745
745
  end
746
746
  ```
747
747
 
748
+ ###### UIAlertController
749
+
750
+ Starting with iOS 8.0, UIActionSheet and UIAlertView are deprecated and replaced by UIAlertController.
751
+
752
+ This is very similar to `UIAlertView.alert` and `UIActionSheet.alert` but you have to pass a `UIViewController` as first argument.
753
+
754
+ Options:
755
+
756
+ UIAlertController.alert(controller, options)
757
+ UIAlertController.alert(controller, title, options)
758
+ 0 => title => String - title of the action sheet
759
+ :title => Title of the alert sheet
760
+ :buttons => [] - List of buttons ([cancel, destructive, others...])
761
+ :style => Symbol | Fixnum - A symbol (uialertcontrollerstyle) or constant (UIAlertControllerStyle*)
762
+ :show => Boolean - Whether to show the alert controller (default: true)
763
+ :from => CGRect | UIBarButtonItem | UIView (default: first window)
764
+ Where to display the alert. Mostly relevant on iPad.
765
+ :view => UIView (default: first window)
766
+ The view to display the alert when used with :from => CGRect
767
+
768
+ ```ruby
769
+ # simple
770
+ UIAlertController.alert(self, 'This is happening, OK?', buttons: ['Cancel', 'Kill it!', 'Uh, what?']
771
+ ) do |button|
772
+ # button is 'Cancel', 'Kill it!' or 'Uh, what?'
773
+ end
774
+ ```
775
+
748
776
  ###### UIButton
749
777
  ```ruby
750
778
  UIButton.buttonWithType(:custom.uibuttontype)
@@ -193,6 +193,14 @@ class Symbol
193
193
  end
194
194
  alias uiactionsheetstyle uiactionstyle
195
195
 
196
+ def uialertcontrollerstyle
197
+ SugarCube.look_in(self, Symbol.uialertcontrollerstyle)
198
+ end
199
+
200
+ def uialertactionstyle
201
+ SugarCube.look_in(self, Symbol.uialertactionstyle)
202
+ end
203
+
196
204
  def uiimagesource
197
205
  SugarCube.look_in(self, Symbol.uiimagesource)
198
206
  end
@@ -289,6 +297,9 @@ class Symbol
289
297
  attr :uialertstyle
290
298
  attr :uiactionstyle
291
299
 
300
+ attr :uialertcontrollerstyle
301
+ attr :uialertactionstyle
302
+
292
303
  attr :uiimagesource
293
304
  attr :uiimagecapture
294
305
  attr :uiimagecamera
@@ -763,6 +774,22 @@ class Symbol
763
774
  login_and_password_input: UIAlertViewStyleLoginAndPasswordInput,
764
775
  }
765
776
 
777
+ if defined?(UIAlertControllerStyleAlert)
778
+ @uialertcontrollerstyle = {
779
+ alert: UIAlertControllerStyleAlert,
780
+ action_sheet: UIAlertControllerStyleActionSheet
781
+ }
782
+
783
+ @uialertactionstyle = {
784
+ default: UIAlertActionStyleDefault,
785
+ cancel: UIAlertActionStyleCancel,
786
+ destructive: UIAlertActionStyleDestructive
787
+ }
788
+ else
789
+ @uialertcontrollerstyle = {}
790
+ @uialertactionstyle = {}
791
+ end
792
+
766
793
  @uiactionstyle = {
767
794
  automatic: UIActionSheetStyleAutomatic,
768
795
  default: UIActionSheetStyleDefault,
@@ -56,7 +56,7 @@ class UIActionSheet
56
56
  # cancelButtonTitle:destructiveButtonTitle:otherButtonTitles:
57
57
  # uses localized buttons in the actual alert
58
58
  if buttons.is_a?(NSDictionary)
59
- button_titles = buttons.keys
59
+ button_keys = buttons.keys
60
60
  if buttons.key?(:cancel)
61
61
  args << (buttons[:cancel] && NSBundle.mainBundle.localizedStringForKey(buttons[:cancel], value: nil, table: nil))
62
62
  else
@@ -69,31 +69,31 @@ class UIActionSheet
69
69
  end
70
70
  args.concat(buttons.select { |k, m| k != :cancel && k != :destructive }.map { |k, m| m && NSBundle.mainBundle.localizedStringForKey(m, value: nil, table: nil) })
71
71
  else
72
- button_titles = buttons
72
+ button_keys = buttons
73
73
  args.concat(buttons.map { |m| m && NSBundle.mainBundle.localizedStringForKey(m, value: nil, table: nil) })
74
74
  end
75
75
  args << nil # otherButtonTitles:..., nil
76
76
 
77
77
  if args[2] && args[3] # cancel && destructive buttons
78
- buttons_mapped[0] = button_titles[1] # destructiveIndex == 0, button == 1
79
- buttons_mapped[button_titles.length - 1] = button_titles[0] # cancelIndex == last, button == 0
78
+ buttons_mapped[0] = button_keys[1] # destructiveIndex == 0, button == 1
79
+ buttons_mapped[button_keys.length - 1] = button_keys[0] # cancelIndex == last, button == 0
80
80
  # from first+1 to last-1
81
- button_titles[2..-1].each_with_index do |button,index|
81
+ button_keys[2..-1].each_with_index do |button,index|
82
82
  buttons_mapped[index + 1] = button
83
83
  end
84
84
  elsif args[3] # destructive button
85
- buttons_mapped[0] = button_titles[1] # destructiveIndex == 0, button == 1
85
+ buttons_mapped[0] = button_keys[1] # destructiveIndex == 0, button == 1
86
86
  # from first+1 to last-1
87
87
  buttons[2..-1].each_with_index do |button,index|
88
88
  buttons_mapped[index + 1] = button
89
89
  end
90
90
  elsif args[2] # cancel button
91
- buttons_mapped[buttons.length - 2] = button_titles[0] # cancelIndex == last, button == 0
92
- button_titles[2..-1].each_with_index do |button,index|
91
+ buttons_mapped[buttons.length - 2] = button_keys[0] # cancelIndex == last, button == 0
92
+ button_keys[2..-1].each_with_index do |button,index|
93
93
  buttons_mapped[index] = button
94
94
  end
95
95
  else
96
- button_titles[2..-1].each_with_index do |button,index|
96
+ button_keys[2..-1].each_with_index do |button,index|
97
97
  buttons_mapped[index] = button
98
98
  end
99
99
  end
@@ -0,0 +1,112 @@
1
+ class UIAlertController
2
+
3
+ attr_accessor :sugarcube_handler
4
+
5
+ # @example
6
+ # UIAlertController.alert(controller, "title",
7
+ # message: "help!",
8
+ # buttons: %w"Cancel OK No-way"
9
+ # ) { |pressed| } # pressed will be Cancel OK No-way
10
+ def self.alert(controller, title, options={}, more_options={}, &block)
11
+ if title.is_a?(NSDictionary)
12
+ options = title
13
+ title = options[:title]
14
+ message = options[:message]
15
+ elsif options.is_a? String
16
+ message = options
17
+ options = more_options
18
+ else
19
+ message = options[:message]
20
+ end
21
+
22
+ style = options[:style] || UIAlertControllerStyleAlert
23
+ style = style.uialertcontrollerstyle if style.respond_to?(:uialertcontrollerstyle)
24
+
25
+ alert = self.alertControllerWithTitle(title, message: message, preferredStyle: style)
26
+
27
+ buttons = options[:buttons]
28
+ if buttons.nil?
29
+ buttons = %w(OK Cancel)
30
+ end
31
+
32
+ if block
33
+ alert.sugarcube_handler = SugarCube::UIAlertControllerCallbackHelper.new(block)
34
+ end
35
+
36
+ if buttons.is_a?(NSDictionary)
37
+ button_keys = buttons.keys
38
+ buttons = buttons.values
39
+ else
40
+ button_keys = buttons
41
+ end
42
+ buttons.each_with_index do |button, index|
43
+ key = button_keys[index]
44
+ case key
45
+ when :cancel, 'Cancel'
46
+ action_style = UIAlertActionStyleCancel
47
+ button = 'Cancel' if button == :cancel
48
+ when :destructive, 'Destructive'
49
+ action_style = UIAlertActionStyleDestructive
50
+ button = 'Destructive' if button == :destructive
51
+ else
52
+ action_style = UIAlertActionStyleDefault
53
+ end
54
+ label = NSBundle.mainBundle.localizedStringForKey(button, value: nil, table: nil)
55
+ action = UIAlertAction.actionWithTitle(label,
56
+ style: action_style,
57
+ handler: proc { |_|
58
+ alert.sugarcube_handler.call(key) unless alert.sugarcube_handler.nil?
59
+ })
60
+ alert.addAction action
61
+ end
62
+
63
+ if style == UIAlertControllerStyleActionSheet and UIDevice.currentDevice.userInterfaceIdiom == :ipad.uidevice
64
+ alert.modalPresentationStyle = UIModalPresentationPopover
65
+ alert.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny
66
+
67
+ from = options.fetch(:from, UIApplication.sharedApplication.windows[0])
68
+ case from
69
+ when CGRect
70
+ view = options.fetch(:view, UIApplication.sharedApplication.windows[0])
71
+ alert.popoverPresentationController.sourceView = view
72
+ alert.popoverPresentationController.sourceRect = from
73
+ when UIBarButtonItem
74
+ alert.popoverPresentationController.barButtonItem = from
75
+ when UIView
76
+ frame = [[CGRectGetMidX(from.bounds), CGRectGetMidY(from.bounds)], [1.0, 1.0]]
77
+ alert.popoverPresentationController.sourceView = from
78
+ alert.popoverPresentationController.sourceRect = frame
79
+ else
80
+ raise "Unknown :from option #{from.inspect}"
81
+ end
82
+ end
83
+
84
+ if options.fetch(:show, true)
85
+ controller.presentViewController(alert, animated: true, completion: nil)
86
+ end
87
+
88
+ alert
89
+ end
90
+
91
+ def <<(title)
92
+ action = UIAlertAction.actionWithTitle(title,
93
+ style: UIAlertActionStyleDefault,
94
+ handler: proc { |_|
95
+ sugarcube_handler.call(title) unless sugarcube_handler.nil?
96
+ })
97
+ addAction action
98
+ end
99
+ end
100
+
101
+ module SugarCube
102
+ class UIAlertControllerCallbackHelper
103
+
104
+ def initialize(callback)
105
+ @callback = callback.respond_to?('weak!') ? callback.weak! : callback
106
+ end
107
+
108
+ def call(button)
109
+ @callback.call(button)
110
+ end
111
+ end
112
+ end
@@ -65,7 +65,7 @@ class UIAlertView
65
65
 
66
66
  # uses localized buttons in the actual alert
67
67
  if buttons.is_a?(NSDictionary)
68
- button_titles = buttons.keys
68
+ button_keys = buttons.keys
69
69
  if buttons.key?(:cancel)
70
70
  args << (buttons[:cancel] && NSBundle.mainBundle.localizedStringForKey(buttons[:cancel], value: nil, table: nil))
71
71
  else
@@ -73,10 +73,10 @@ class UIAlertView
73
73
  end
74
74
  args.concat(buttons.select { |k, m| k != :cancel }.map { |k, m| m && NSBundle.mainBundle.localizedStringForKey(m, value: nil, table: nil) })
75
75
  else
76
- button_titles = buttons
76
+ button_keys = buttons
77
77
  args.concat(buttons.map { |m| m && NSBundle.mainBundle.localizedStringForKey(m, value: nil, table: nil) })
78
78
  end
79
- delegate.buttons = button_titles
79
+ delegate.buttons = button_keys
80
80
  args << nil # otherButtonTitles:..., nil
81
81
 
82
82
  alert = self.alloc
@@ -1,3 +1,3 @@
1
1
  module SugarCube
2
- Version = '2.2.0'
2
+ Version = '2.3.0'
3
3
  end
@@ -411,6 +411,17 @@ describe "Symbol - constants" do
411
411
  :black_opaque.uiactionstyle.should == UIActionSheetStyleBlackOpaque
412
412
  end
413
413
 
414
+ it 'should support `uialertcontrollerstyle`' do
415
+ :alert.uialertcontrollerstyle.should == UIAlertControllerStyleAlert
416
+ :action_sheet.uialertcontrollerstyle.should == UIAlertControllerStyleActionSheet
417
+ end
418
+
419
+ it 'should support `uialertactionstyle`' do
420
+ :default.uialertactionstyle.should == UIAlertActionStyleDefault
421
+ :cancel.uialertactionstyle.should == UIAlertActionStyleCancel
422
+ :destructive.uialertactionstyle.should == UIAlertActionStyleDestructive
423
+ end
424
+
414
425
  it 'should support `uiimagesource`' do
415
426
  :camera.uiimagesource.should == UIImagePickerControllerSourceTypeCamera
416
427
  :library.uiimagesource.should == UIImagePickerControllerSourceTypePhotoLibrary
@@ -853,6 +864,14 @@ describe "Symbol - constants" do
853
864
  should.raise(SugarCubeNotFoundException) { :definitely_doesnt_exist_i_am_really_sure_of_it.uiactionstyle }
854
865
  end
855
866
 
867
+ it 'should not find nonexistant `uialertcontrollerstyle`' do
868
+ should.raise(SugarCubeNotFoundException) { :definitely_doesnt_exist_i_am_really_sure_of_it.uialertcontrollerstyle }
869
+ end
870
+
871
+ it 'should not find nonexistant `uialertactionstyle`' do
872
+ should.raise(SugarCubeNotFoundException) { :definitely_doesnt_exist_i_am_really_sure_of_it.uialertactionstyle }
873
+ end
874
+
856
875
  it 'should not find nonexistant `uiimagesource`' do
857
876
  should.raise(SugarCubeNotFoundException) { :definitely_doesnt_exist_i_am_really_sure_of_it.uiimagesource }
858
877
  end
@@ -0,0 +1,130 @@
1
+ describe UIAlertController do
2
+ tests UIViewController
3
+
4
+ it 'should have :show option (show: false)' do
5
+ alert = UIAlertController.alert(controller, 'test', show: false)
6
+ wait 0.6 do
7
+ alert.presentingViewController.should == nil
8
+ end
9
+ end
10
+
11
+ it 'should show by default' do
12
+ alert = UIAlertController.alert(controller, 'test')
13
+ wait 0.6 do
14
+ alert.presentingViewController.should == controller
15
+ controller.dismissViewControllerAnimated(false, completion: nil)
16
+ end
17
+ end
18
+
19
+ it 'should assign the title' do
20
+ alert = UIAlertController.alert(controller, 'test title', show: false)
21
+ alert.title.should == 'test title'
22
+ wait 0.001 do
23
+ controller.dismissViewControllerAnimated(false, completion: nil)
24
+ end
25
+ end
26
+
27
+ it 'should assign the title by options' do
28
+ alert = UIAlertController.alert(controller, title: 'test title', show: false)
29
+ alert.title.should == 'test title'
30
+ wait 0.001 do
31
+ controller.dismissViewControllerAnimated(false, completion: nil)
32
+ end
33
+ end
34
+
35
+ it 'should have :style option' do
36
+ Symbol.uialertcontrollerstyle.each do |style, value|
37
+ # as symbol
38
+ alert = UIAlertController.alert(controller, 'test', show: false, style: style)
39
+ alert.preferredStyle.should == value
40
+
41
+ # as constant
42
+ alert = UIAlertController.alert(controller, 'test', show: false, style: value)
43
+ alert.preferredStyle.should == value
44
+ end
45
+ end
46
+
47
+ it 'should have :from option that accepts CGRect' do
48
+ alert = UIAlertController.alert(controller, 'test', from: CGRect.new([0, 0], [320, 0]))
49
+ wait 0.6 do
50
+ alert.presentingViewController.should == controller
51
+ controller.dismissViewControllerAnimated(false, completion: nil)
52
+ end
53
+ end
54
+
55
+
56
+ it 'should have :from option that accepts CGRect and a :view that accepts UIView' do
57
+ view = UIView.alloc.initWithFrame(UIScreen.mainScreen.bounds)
58
+ window = UIApplication.sharedApplication.windows[0]
59
+ window << view
60
+ alert = UIAlertController.alert(controller, 'test', from: CGRect.new([0, 0], [320, 0]), view: view)
61
+ wait 0.6 do
62
+ alert.presentingViewController.should == controller
63
+ controller.dismissViewControllerAnimated(false, completion: nil)
64
+ end
65
+ end
66
+
67
+ it 'should have :from option that accepts UIBarButtonItem' do
68
+ button = UIBarButtonItem.done
69
+ toolbar = UIToolbar.alloc.initWithFrame(UIScreen.mainScreen.bounds)
70
+ toolbar.items = [button]
71
+ window = UIApplication.sharedApplication.windows[0]
72
+ window << toolbar
73
+ alert = UIAlertController.alert(controller, 'test', from: button)
74
+ wait 0.6 do
75
+ alert.presentingViewController.should == controller
76
+ controller.dismissViewControllerAnimated(false, completion: nil)
77
+ end
78
+ end
79
+
80
+ it 'should have :from option that accepts UIView' do
81
+ view = UIView.alloc.initWithFrame(UIScreen.mainScreen.bounds)
82
+ window = UIApplication.sharedApplication.windows[0]
83
+ window << view
84
+ alert = UIAlertController.alert(controller, 'test', from: view)
85
+ wait 0.6 do
86
+ alert.presentingViewController.should == controller
87
+ controller.dismissViewControllerAnimated(false, completion: nil)
88
+ end
89
+ end
90
+
91
+ it 'should add a button with << method' do
92
+ alert = UIAlertController.alert(controller, 'test', show: false)
93
+ alert << 'title'
94
+ alert.actions.lastObject.title.should == 'title'
95
+ end
96
+
97
+ it 'should show "OK" by default as first button' do
98
+ alert = UIAlertController.alert(controller, 'test', show: false)
99
+ alert.actions[0].title.should == 'OK'
100
+ end
101
+
102
+ it 'should show "Cancel" by default as second button' do
103
+ alert = UIAlertController.alert(controller, 'test', show: false)
104
+ alert.actions[1].title.should == 'Cancel'
105
+ end
106
+
107
+ it 'should have :buttons option' do
108
+ alert = UIAlertController.alert(controller, 'test', :buttons => %w(Hello World From Test), show: false)
109
+ alert.actions.count.should == 4
110
+ end
111
+
112
+ it 'should support Hash for :buttons option' do
113
+ alert = UIAlertController.alert(controller, 'test', :buttons => {
114
+ cancel: 'Nevermind',
115
+ ok: 'OK',
116
+ destructive: 'Do eet',
117
+ other: 'Other',
118
+ }, show: false)
119
+ alert.actions.count.should == 4
120
+ alert.actions[0].title.should == 'Nevermind'
121
+ alert.actions[0].style.should == UIAlertActionStyleCancel
122
+ alert.actions[1].title.should == 'OK'
123
+ alert.actions[1].style.should == UIAlertActionStyleDefault
124
+ alert.actions[2].title.should == 'Do eet'
125
+ alert.actions[2].style.should == UIAlertActionStyleDestructive
126
+ alert.actions[3].title.should == 'Other'
127
+ alert.actions[3].style.should == UIAlertActionStyleDefault
128
+ end
129
+
130
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sugarcube
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Colin T.A. Gray
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-09-17 00:00:00.000000000 Z
14
+ date: 2014-09-18 00:00:00.000000000 Z
15
15
  dependencies: []
16
16
  description: |
17
17
  == Description
@@ -105,6 +105,7 @@ files:
105
105
  - lib/ios/sugarcube-factories/nserror.rb
106
106
  - lib/ios/sugarcube-factories/uiactionsheet.rb
107
107
  - lib/ios/sugarcube-factories/uiactivityindicatorview.rb
108
+ - lib/ios/sugarcube-factories/uialertcontroller.rb
108
109
  - lib/ios/sugarcube-factories/uialertview.rb
109
110
  - lib/ios/sugarcube-factories/uibarbuttonitem.rb
110
111
  - lib/ios/sugarcube-factories/uibutton.rb
@@ -245,6 +246,7 @@ files:
245
246
  - spec/ios/symbol_uifont_spec.rb
246
247
  - spec/ios/timer_spec.rb
247
248
  - spec/ios/uiactionsheet_spec.rb
249
+ - spec/ios/uialertcontroller_spec.rb
248
250
  - spec/ios/uialertview_spec.rb
249
251
  - spec/ios/uibarbuttonitem_spec.rb
250
252
  - spec/ios/uicolor_spec.rb
@@ -333,6 +335,7 @@ test_files:
333
335
  - spec/ios/symbol_uifont_spec.rb
334
336
  - spec/ios/timer_spec.rb
335
337
  - spec/ios/uiactionsheet_spec.rb
338
+ - spec/ios/uialertcontroller_spec.rb
336
339
  - spec/ios/uialertview_spec.rb
337
340
  - spec/ios/uibarbuttonitem_spec.rb
338
341
  - spec/ios/uicolor_spec.rb