Last active
March 15, 2016 07:40
-
-
Save s4y/62ad92fda13daae8c081 to your computer and use it in GitHub Desktop.
A function for showing alerts and action sheets, written for iOS 7 and 8
This file contains hidden or 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
import UIKit | |
// Notes: | |
// - You must explicitly weak link to UIKit to support iOS 7 | |
// - Action sheets on iOS 7 only show a title | |
func showAlert(viewController: UIViewController, style: UIAlertControllerStyle = .Alert, title: String? = nil, message: String? = nil, sourceView: UIView? = nil, completion: (() -> ())? = nil, buttons: (UIAlertActionStyle, String, (() -> ())?)...) { | |
if (NSClassFromString("UIAlertController") != nil) { | |
// iOS 8+ | |
let alertController = UIAlertController(title: title, message: message, preferredStyle: style) | |
for button in buttons { | |
alertController.addAction(UIAlertAction(title: button.1, style: button.0) { (_: UIAlertAction!) in | |
if let completion = completion { completion() } | |
if let cb = button.2 { cb() } | |
}) | |
} | |
if let sourceView = sourceView { | |
if let popoverPresentationController = alertController.popoverPresentationController { | |
popoverPresentationController.sourceView = sourceView | |
popoverPresentationController.sourceRect = sourceView.bounds | |
} | |
} | |
viewController.presentViewController(alertController, animated: true, completion: nil) | |
} else { | |
// iOS 7 | |
class Helper: NSObject { | |
var holdSelf: Helper? | |
var cb: (Int) -> () | |
init(cb: (Int) -> ()) { | |
self.cb = cb | |
super.init() | |
self.holdSelf = self | |
} | |
func finish(index: Int) { | |
self.cb(index) | |
self.holdSelf = nil | |
} | |
} | |
switch style { | |
case .ActionSheet: | |
class ActionSheetHelper : Helper, UIActionSheetDelegate { | |
init(_ actionSheet: UIActionSheet, cb: (Int) -> ()) { | |
super.init(cb: cb) | |
actionSheet.delegate = self | |
} | |
func actionSheet(actionSheet: UIActionSheet!, clickedButtonAtIndex buttonIndex: Int) { | |
actionSheet.delegate = nil | |
self.finish(buttonIndex) | |
} | |
} | |
let actionSheet = UIActionSheet() | |
if let title = title { | |
actionSheet.title = title | |
} | |
for button in buttons { | |
actionSheet.addButtonWithTitle(button.1) | |
switch button.0 { | |
case .Default: | |
break | |
case .Cancel: | |
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons - 1 | |
case .Destructive: | |
actionSheet.destructiveButtonIndex = actionSheet.numberOfButtons - 1 | |
} | |
} | |
ActionSheetHelper(actionSheet) { | |
if let completion = completion { completion() } | |
if let cb = buttons[$0].2 { cb() } | |
} | |
if let sourceView = sourceView { | |
actionSheet.showFromRect(sourceView.bounds, inView: sourceView, animated: true) | |
} else { | |
actionSheet.showInView(viewController.view) | |
} | |
case .Alert: | |
class AlertHelper : Helper, UIAlertViewDelegate { | |
init(_ alertView: UIAlertView, cb: (Int) -> ()) { | |
super.init(cb: cb) | |
alertView.delegate = self | |
} | |
func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int) { | |
alertView.delegate = nil | |
self.finish(buttonIndex) | |
} | |
} | |
let alertView = UIAlertView() | |
if let title = title { | |
alertView.title = title | |
} | |
if let message = message { | |
alertView.message = message | |
} | |
for button in buttons { | |
alertView.addButtonWithTitle(button.1) | |
switch button.0 { | |
case .Cancel: | |
alertView.cancelButtonIndex = alertView.numberOfButtons - 1 | |
default: | |
break | |
} | |
} | |
AlertHelper(alertView) { | |
if let completion = completion { completion() } | |
if let cb = buttons[$0].2 { cb() } | |
} | |
alertView.show() | |
} | |
} | |
} |
How to use this?
how yo use this?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ifabijanovic were you able to get this to work? I'm still having the problem of the delegate method never getting called on iOS7. Any ideas? I made the change you suggested but still nothing. I'm running XCode 6.3.1 and Swift 1.2 on an iPhone 4S running 7.0.1.