Skip to content

Instantly share code, notes, and snippets.

@mgp
Created February 26, 2015 22:43
Show Gist options
  • Save mgp/6ca63f80283d1090a243 to your computer and use it in GitHub Desktop.
Save mgp/6ca63f80283d1090a243 to your computer and use it in GitHub Desktop.
OwnedDelegateAlertView
//
// ViewController.swift
// deinit-failure
//
// Created by Mike Parker on 2/26/15.
// Copyright (c) 2015 Mike Parker. All rights reserved.
//
import UIKit
/**
A UIAlertView that owns its delegate so that the client that displays the UIAlertView
does not need to own it.
This is useful when the client that displays the UIAlertView is not the UIAlertDelegate
implementation. It is free to initialize an object to serve as the delegate that exists
only for the lifetime of the UIAlertView, thereby fostering decomposition.
*/
private class OwnedDelegateAlertView: UIAlertView {
private let ownedDelegate: UIAlertViewDelegate?
override init(title: String?, message: String?, delegate: AnyObject?, cancelButtonTitle: String?) {
ownedDelegate = delegate as UIAlertViewDelegate?
super.init(title: title, message: message, delegate: nil, cancelButtonTitle: cancelButtonTitle)
}
convenience init(title: String, message: String, delegate: UIAlertViewDelegate, cancelButtonTitle: String, otherButtonTitles firstButtonTitle: String, _ moreButtonTitles: String...) {
self.init(title: title, message: message, delegate: delegate, cancelButtonTitle: cancelButtonTitle)
addButtonWithTitle(firstButtonTitle)
for buttonTitle in moreButtonTitles {
self.addButtonWithTitle(buttonTitle)
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(frame: CGRect) { super.init(frame: frame) }
deinit {
println("running deinit for uialertview")
}
}
/**
UIAlertViewDelegate used when the user can only go back, and so the associated handler
has no parameters.
*/
private class BackOnlyErrorDelegate: NSObject, UIAlertViewDelegate {
private let handler: () -> Void
init(handler: () -> Void) {
self.handler = handler
super.init()
}
func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
switch buttonIndex {
case alertView.cancelButtonIndex:
handler()
default:
fatalError("UIAlertView selected an option that was not cancel")
}
}
deinit {
println("running deinit for delegate")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delay, dispatch_get_main_queue()) {
self.displayAlertViewWithHandler(self.handlerForAlertView())
}
}
private func displayAlertViewWithHandler(handler: () -> Void) {
let delegate = BackOnlyErrorDelegate(handler: handler)
let title = NSLocalizedString("the title", comment: "Title for alert view upon UIWebView failure")
let message = "the message"
let cancelButtonTitle = "cancel"
let alertView = OwnedDelegateAlertView(title: title, message: message, delegate: delegate, cancelButtonTitle: cancelButtonTitle)
alertView.show()
}
private func handlerForAlertView() -> () -> Void {
return { [weak self] () -> Void in
println("Handler invoked")
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment