Wrap UIAlertView

Inspired by @rbeene and #201, I present `BW::UIAlertView` - a subclass of `UIAlertView` with an idiomatic Ruby syntax.  

#### Default alert

The `.default` constructor accepts an optional `Hash` of options and returns a `BW::UIAlertView` instance in the `UIAlertViewStyleDefault` style.  The instance can then be given an `#on_click` callback to be executed when it's button is clicked.  For example:

![iOS Simulator Screen shot Apr 24 2013 10 54 28 AM](https://f.cloud.github.com/assets/5688/421437/59a5376c-ad08-11e2-9ccc-0df83eb360e0.png)

```ruby
alert = BW::UIAlertView.default(:title => "Are you ready?")

alert.on_click do |alert|
 # ...
end

alert.show
```

The same thing can be accomplished by chaining the `on_click` callback off the constructor

```ruby
alert = BW::UIAlertView.default(:title => "Are you ready?").on_click do |alert|
 # ...
end

alert.show
```

Or by passing a block directly to the constructor

```ruby
alert = BW::UIAlertView.default(:title => "Are you ready?") do |alert|
 # ...
end

alert.show
```

Or by providing the callback as an `:on_click` argument to the constructor.

```ruby
callback = -> do |alert|
  # ...
end

alert = BW::UIAlertView.default(:title => "Are you ready?", :on_click => callback)

alert.show
```

If both are provided, the `:on_click` argument is prioritized over a block.

#### Input alerts

`BW::UIAlertView` has constructors for input alerts too.  Each constructor accepts an optional `Hash` of options and an optional block for the `on_click` callback.

`.plain_text_input` returns an instance in the `UIAlertViewStylePlainTextInput` style.

![iOS Simulator Screen shot Apr 24 2013 10 58 27 AM](https://f.cloud.github.com/assets/5688/421453/a6c15698-ad08-11e2-9bef-a755732e9b91.png)

```ruby
alert = BW::UIAlertView.plain_text_input(:title => "Replicator") do |alert|
  alert.plain_text_field.text    #=> "Tea. Early Grey. Hot."
end

alert.show
```

`.secure_text_input` returns an instance in the `UIAlertViewStyleSecureTextInput` style.

![iOS Simulator Screen shot Apr 24 2013 11 09 43 AM](https://f.cloud.github.com/assets/5688/421503/396084dc-ad0a-11e2-9e09-c778d2a6cdc4.png)

```ruby
alert = BW::UIAlertView.secure_text_input(:title => "Authorization") do |alert|
  alert.secure_text_field.text   #=> "Theta2997"
end

alert.show
```

And `.login_and_password_input` returns an instance in the `UIAlertViewStyleLoginAndPasswordInput` style.

![iOS Simulator Screen shot Apr 24 2013 11 27 20 AM](https://f.cloud.github.com/assets/5688/421608/b26ab51c-ad0c-11e2-8356-d73fd20c8d7f.png)

```ruby
alert = BW::UIAlertView.login_and_password_input(:title => "Authorization") do |alert|
  alert.login_text_field.text    #=> "La Forge"
  alert.password_text_field.text #=> "Theta2997"
end

alert.show
```
#### Buttons

Each alert style has sane, default button titles.  Yet they're fully customizable by providing either a `String` to the constructor's `:buttons` argument

![iOS Simulator Screen shot Apr 24 2013 11 34 12 AM](https://f.cloud.github.com/assets/5688/421633/ac364106-ad0d-11e2-9b0a-ec1692da0c7f.png)

```ruby
alert = BW::UIAlertView.default(:title => "BubbleWrap is", :buttons => "Awesome")

alert.show
```

Or an `Array` of strings to the constructor's `:buttons` argument.

![iOS Simulator Screen shot Apr 24 2013 11 35 36 AM](https://f.cloud.github.com/assets/5688/421640/ce9e4d9c-ad0d-11e2-96bd-ca5327570f4d.png)

```ruby
options = {
  :title   => "Dinner this Friday?",
  :message => "My treat!",
  :buttons => ["No", "Maybe", "Yes"]
}
alert = BW::UIAlertView.default(options)

alert.show
```

Inside a callback, the `#clicked_button` method contains the `index` and `title` of the clicked button.  

![iOS Simulator Screen shot Apr 24 2013 11 43 26 AM](https://f.cloud.github.com/assets/5688/421755/d3bf35cc-ad10-11e2-995d-ca45adaad504.png)

```ruby
options = {
  :title   => "Warp Engine Online",
  :message => "Plot a course for Starbase 118.  Warp 7.",
  :buttons => ["Cancel", "Engage"],
}
alert = BW::UIAlertView.default(options) do |alert|
  if alert.clicked_button.index == 0
    # ...
  else
    # ...
  end

  if alert.clicked_button.title == "Cancel"
    # ...
  else
    # ...
  end
end

alert.show
```

When the constructor's `:cancel_button_index` argument is provided, the `clicked_button` knows whether or not it's a `cancel?` button.  Conveniently, the argument is automatically set to `0` for all constructors **EXCEPT** `.default` and `.new`.

![iOS Simulator Screen shot Apr 24 2013 11 43 26 AM](https://f.cloud.github.com/assets/5688/421755/d3bf35cc-ad10-11e2-995d-ca45adaad504.png)

```ruby
options = {
  :title               => "Warp Engine Online",
  :message             => "Plot a course for Starbase 118.  Warp 7.",
  :buttons             => ["Cancel", "Engage"],
  :cancel_button_index => 0 # set for all constructors EXCEPT `.default` and `.new`
}
alert = BW::UIAlertView.default(options) do |alert|
  # NOTE: uses the :cancel_button_index argument
  if alert.clicked_button.cancel?
    # ...
  else
    # ...
  end
end

alert.show
```

#### Callbacks

`BW::UIAlertView` instances are their own delegate.  The complete `UIAlertViewDelegte` protocol is available via callbacks.

```ruby
alert = BW::UIAlertView.default

alert.will_present do |alert|
  # aka willPresentAlertView:
end

alert.did_present do |alert|
  # aka didPresentAlertView:
end

alert.on_click do |alert|
  # aka alertView:clickedButtonAtIndex:
end

alert.will_dismiss do |alert|
  # aka alertView:willDismissWithButtonIndex:
end

alert.did_dismiss do |alert|
  # aka alertView:didDismissWithButtonIndex:
end

alert.on_system_cancel do |alert|
  # aka alertViewCancel:
end

alert.enable_first_other_button? do |alert|
  # aka alertViewShouldEnableFirstOtherButton:
  # NOTE: must return a boolean
  true
end
```

#### Constructor options

The `.new` constructor provides a flexible, builder-style syntax.  It accepts the following options:

```ruby
options = {
  :title                      => "title",
  :message                    => "message",
  :buttons                    => "button title",  # NOTE: either a String or Array
  :style                      => :plain_text_input,
  :cancel_button_index        => 0,
  :will_present               => -> { |a| nil },
  :did_present                => -> { |a| nil },
  :on_click                   => -> { |a| nil },  # NOTE: prioritized over a block
  :will_dismiss               => -> { |a| nil },
  :did_dismiss                => -> { |a| nil },
  :on_system_cancel           => -> { |a| nil },
  :enable_first_other_button? => -> { |a| true }  # NOTE: must return a boolean
}
BW::UIAlertView.new(options)
```
---

Creating this wrapper was a blast!  Thanks again, @rbeene, for the inspiration.  

I'm happy to discuss both the API and the implementation.  Although it may seem complex, there's only a few moving parts under the hood.  I recommend trying the sample app to see it in action.