Created
February 26, 2015 22:43
-
-
Save mgp/6ca63f80283d1090a243 to your computer and use it in GitHub Desktop.
OwnedDelegateAlertView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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