Class: UIActionSheet

Inherits:
Object show all
Defined in:
lib/ios/sugarcube-factories/uiactionsheet.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.alert(title, options = {}, &block) ⇒ Object

For the purposes of whether the cancel or success handler gets called, the first button is considered the 'cancel' button, the second button is the 'destructive' button, and the rest are plain old buttons.

If you use just one block, it will be used for all of the buttons.

Examples:

# use a different handler for each button type
UIActionSheet.alert("title",
  buttons: %w"Cancel Delete No-way",
  cancel: proc{ puts "nevermind" },
  destructive: proc{ puts "OHHH YEAAH!" },
  success: proc{ |pressed| puts "pressed: #{pressed}" },
  )
# use one handler for all buttons
UIActionSheet.alert("title", buttons: [...]) { |button| }

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/ios/sugarcube-factories/uiactionsheet.rb', line 19

def self.alert(title, options={}, &block)
  if title.is_a?(NSDictionary)
    options = title
    title = options[:title]
  end

  # create the delegate
  delegate = SugarCube::ActionSheetDelegate.new
  delegate.on_default = block
  delegate.on_success = options[:success]
  delegate.on_destructive = options[:destructive]
  delegate.on_cancel = options[:cancel]
  delegate.send(:retain)

  args = [title]            # initWithTitle:
  args << delegate          # delegate:

  buttons = (options[:buttons] || []).freeze
  if buttons.empty?
    buttons = []  # an empty Hash becomes an Array

    # cancelButtonTitle:
    buttons << nil

    # destructiveButtonTitle
    buttons << nil

    # otherButtonTitles:
    buttons << 'OK'
  elsif buttons.length == 1 && (options[:cancel] || options[:destructive])
    raise 'If you only have one button, use a :success handler, not :cancel or :destructive'
  end

  # the button titles, mapped to how UIActionSheet orders them.  These are
  # passed to the success handler.
  buttons_mapped = {}

  # cancelButtonTitle:destructiveButtonTitle:otherButtonTitles:
  # uses localized buttons in the actual alert
  if buttons.is_a?(NSDictionary)
    button_keys = buttons.keys
    if buttons.key?(:cancel)
      args << (buttons[:cancel] && NSBundle.mainBundle.localizedStringForKey(buttons[:cancel], value: nil, table: nil))
    else
      args << nil
    end
    if buttons.key?(:destructive)
      args << (buttons[:destructive] && NSBundle.mainBundle.localizedStringForKey(buttons[:destructive], value: nil, table: nil))
    else
      args << nil
    end
    args.concat(buttons.select { |k, m| k != :cancel && k != :destructive }.map { |k, m| m && NSBundle.mainBundle.localizedStringForKey(m, value: nil, table: nil) })
  else
    button_keys = buttons
    args.concat(buttons.map { |m| m && NSBundle.mainBundle.localizedStringForKey(m, value: nil, table: nil) })
  end
  args << nil  # otherButtonTitles:..., nil

  if args[2] && args[3]  # cancel && destructive buttons
    buttons_mapped[0] = button_keys[1]                   # destructiveIndex == 0, button == 1
    buttons_mapped[button_keys.length - 1] = button_keys[0]  # cancelIndex == last, button == 0
    # from first+1 to last-1
    button_keys[2..-1].each_with_index do |button,index|
      buttons_mapped[index + 1] = button
    end
  elsif args[3]  # destructive button
    buttons_mapped[0] = button_keys[1]                   # destructiveIndex == 0, button == 1
    # from first+1 to last-1
    buttons[2..-1].each_with_index do |button,index|
      buttons_mapped[index + 1] = button
    end
  elsif args[2]  # cancel button
    buttons_mapped[buttons.length - 2] = button_keys[0]  # cancelIndex == last, button == 0
    button_keys[2..-1].each_with_index do |button,index|
      buttons_mapped[index] = button
    end
  else
    button_keys[2..-1].each_with_index do |button,index|
      buttons_mapped[index] = button
    end
  end
  delegate.buttons = buttons_mapped

  alert = self.alloc
  alert.send('initWithTitle:delegate:cancelButtonTitle:destructiveButtonTitle:otherButtonTitles:', *args)

  if options.key?(:style)
    style = options[:style]
    if style.respond_to?(:uiactionstyle)
      style = style.uiactionstyle
    end
    alert.actionSheetStyle = style
  end

  if options.fetch(:show, true)
    if options.key?(:from)
      from = options[:from]
    else
      from = UIApplication.sharedApplication.windows[0]
    end

    case from
    when CGRect
      view = options.fetch(:view, UIApplication.sharedApplication.windows[0])
      alert.showFromRect(from, inView: view, animated: true)
    when UIBarButtonItem
      alert.showFromBarButtonItem(from, animated: true)
    when UIToolbar
      alert.showFromToolbar(from)
    when UITabBar
      alert.showFromTabBar(from)
    when UIView
      alert.showInView(from)
    else
      raise "Unknown :from option #{from.inspect}"
    end
  end

  alert
end

Instance Method Details

#<<(title) ⇒ Object


140
141
142
# File 'lib/ios/sugarcube-factories/uiactionsheet.rb', line 140

def <<(title)
  addButtonWithTitle(title)
end