Skip to content

Instantly share code, notes, and snippets.

@s4y
Last active March 15, 2016 07:40
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save s4y/62ad92fda13daae8c081 to your computer and use it in GitHub Desktop.
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
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()
}
}
}
@ifabijanovic
Copy link

Hey, it looks like the UIAlertViewDelegate clickedButtonAtIndex method signature changed since you wrote this code which causes the delegate method to never be called on iOS7. If you change the alertView parameter from UIAlertView! to UIAlertView it works again :)

@blakeperdue
Copy link

@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.

@neoighodaro
Copy link

How to use this?

@iamjaswanth
Copy link

how yo use this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment