How to present iOS UIActionSheet in Swift? - ios

How can I present a UIActionSheet in Swift within an iOS app?
Here is my code for displaying a UIActionSheet:
#IBAction func downloadSheet(sender: AnyObject) {
let optionMenu = UIAlertController(title: nil, message: "Choose Option", preferredStyle: .actionSheet)
let saveAction = UIAlertAction(title: "Save", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
println("Saved")
})
let deleteAction = UIAlertAction(title: "Delete", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
println("Deleted")
})
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
(alert: UIAlertAction!) -> Void in
println("Cancelled")
})
optionMenu.addAction(deleteAction)
optionMenu.addAction(saveAction)
optionMenu.addAction(cancelAction)
self.presentViewController(optionMenu, animated: true, completion: nil)
}

Updated for Swift 4/5
Works for iOS 11-14
Some of the other answers are okay but I ended up mixing and matching a few of them to rather come up with this :
#IBAction func showAlert(sender: AnyObject) {
let alert = UIAlertController(title: "Title", message: "Please Select an Option", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Approve", style: .default , handler:{ (UIAlertAction)in
print("User click Approve button")
}))
alert.addAction(UIAlertAction(title: "Edit", style: .default , handler:{ (UIAlertAction)in
print("User click Edit button")
}))
alert.addAction(UIAlertAction(title: "Delete", style: .destructive , handler:{ (UIAlertAction)in
print("User click Delete button")
}))
alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler:{ (UIAlertAction)in
print("User click Dismiss button")
}))
//uncomment for iPad Support
//alert.popoverPresentationController?.sourceView = self.view
self.present(alert, animated: true, completion: {
print("completion block")
})
}
Enjoy :)

Your Approach is fine, but you can add UIActionSheet with other way with ease.
You can add UIActionSheetDelegate in UIViewController` like
class ViewController: UIViewController ,UIActionSheetDelegate
Set you method like,
#IBAction func downloadSheet(sender: AnyObject)
{
let actionSheet = UIActionSheet(title: "Choose Option", delegate: self, cancelButtonTitle: "Cancel", destructiveButtonTitle: nil, otherButtonTitles: "Save", "Delete")
actionSheet.showInView(self.view)
}
You can get your button index when it clicked like
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int)
{
println("\(buttonIndex)")
switch (buttonIndex){
case 0:
println("Cancel")
case 1:
println("Save")
case 2:
println("Delete")
default:
println("Default")
//Some code here..
}
}
Update 1: for iOS8+
//Create the AlertController and add Its action like button in Actionsheet
let actionSheetControllerIOS8: UIAlertController = UIAlertController(title: "Please select", message: "Option to select", preferredStyle: .ActionSheet)
let cancelActionButton = UIAlertAction(title: "Cancel", style: .cancel) { _ in
print("Cancel")
}
actionSheetControllerIOS8.addAction(cancelActionButton)
let saveActionButton = UIAlertAction(title: "Save", style: .default)
{ _ in
print("Save")
}
actionSheetControllerIOS8.addAction(saveActionButton)
let deleteActionButton = UIAlertAction(title: "Delete", style: .default)
{ _ in
print("Delete")
}
actionSheetControllerIOS8.addAction(deleteActionButton)
self.present(actionSheetControllerIOS8, animated: true, completion: nil)

UIActionSheet is deprecated in iOS 8.
I am using following:
// Create the AlertController
let actionSheetController = UIAlertController(title: "Please select", message: "How you would like to utilize the app?", preferredStyle: .ActionSheet)
// Create and add the Cancel action
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
// Just dismiss the action sheet
}
actionSheetController.addAction(cancelAction)
// Create and add first option action
let takePictureAction = UIAlertAction(title: "Consumer", style: .Default) { action -> Void in
self.performSegueWithIdentifier("segue_setup_customer", sender: self)
}
actionSheetController.addAction(takePictureAction)
// Create and add a second option action
let choosePictureAction = UIAlertAction(title: "Service provider", style: .Default) { action -> Void in
self.performSegueWithIdentifier("segue_setup_provider", sender: self)
}
actionSheetController.addAction(choosePictureAction)
// We need to provide a popover sourceView when using it on iPad
actionSheetController.popoverPresentationController?.sourceView = sender as UIView
// Present the AlertController
self.presentViewController(actionSheetController, animated: true, completion: nil)

Updated for Swift 3.x, Swift 4.x, Swift 5.x
// create an actionSheet
let actionSheetController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
// create an action
let firstAction: UIAlertAction = UIAlertAction(title: "First Action", style: .default) { action -> Void in
print("First Action pressed")
}
let secondAction: UIAlertAction = UIAlertAction(title: "Second Action", style: .default) { action -> Void in
print("Second Action pressed")
}
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in }
// add actions
actionSheetController.addAction(firstAction)
actionSheetController.addAction(secondAction)
actionSheetController.addAction(cancelAction)
// present an actionSheet...
// present(actionSheetController, animated: true, completion: nil) // doesn't work for iPad
actionSheetController.popoverPresentationController?.sourceView = yourSourceViewName // works for both iPhone & iPad
present(actionSheetController, animated: true) {
print("option menu presented")
}

Update for Swift 3:
// Create the AlertController and add its actions like button in ActionSheet
let actionSheetController = UIAlertController(title: "Please select", message: "Option to select", preferredStyle: .actionSheet)
let cancelActionButton = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
print("Cancel")
}
actionSheetController.addAction(cancelActionButton)
let saveActionButton = UIAlertAction(title: "Save", style: .default) { action -> Void in
print("Save")
}
actionSheetController.addAction(saveActionButton)
let deleteActionButton = UIAlertAction(title: "Delete", style: .default) { action -> Void in
print("Delete")
}
actionSheetController.addAction(deleteActionButton)
self.present(actionSheetController, animated: true, completion: nil)

Generetic Action Sheet working for Swift 4, 4.2, 5
If you like a generic version that you can call from every ViewController and in every project try this one:
class Alerts {
static func showActionsheet(viewController: UIViewController, title: String, message: String, actions: [(String, UIAlertActionStyle)], completion: #escaping (_ index: Int) -> Void) {
let alertViewController = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
for (index, (title, style)) in actions.enumerated() {
let alertAction = UIAlertAction(title: title, style: style) { (_) in
completion(index)
}
alertViewController.addAction(alertAction)
}
// iPad Support
alertViewController.popoverPresentationController?.sourceView = viewController.view
viewController.present(alertViewController, animated: true, completion: nil)
}
}
Call like this in your ViewController.
var actions: [(String, UIAlertActionStyle)] = []
actions.append(("Action 1", UIAlertActionStyle.default))
actions.append(("Action 2", UIAlertActionStyle.destructive))
actions.append(("Action 3", UIAlertActionStyle.cancel))
//self = ViewController
Alerts.showActionsheet(viewController: self, title: "D_My ActionTitle", message: "General Message in Action Sheet", actions: actions) { (index) in
print("call action \(index)")
/*
results
call action 0
call action 1
call action 2
*/
}
Attention: Maybe you're wondering why I add Action 1/2/3 but got results like 0,1,2. In the line for (index, (title, style)) in actions.enumerated() I get the index of actions. Arrays always begin with the index 0. So the completion is 0,1,2.
If you like to set a enum, an id or another identifier I would recommend to hand over an object in parameter actions.

Action Sheet in iOS10 with Swift3.0. Follow this link.
#IBAction func ShowActionSheet(_ sender: UIButton) {
// Create An UIAlertController with Action Sheet
let optionMenuController = UIAlertController(title: nil, message: "Choose Option from Action Sheet", preferredStyle: .actionSheet)
// Create UIAlertAction for UIAlertController
let addAction = UIAlertAction(title: "Add", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
print("File has been Add")
})
let saveAction = UIAlertAction(title: "Edit", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
print("File has been Edit")
})
let deleteAction = UIAlertAction(title: "Delete", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
print("File has been Delete")
})
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancel")
})
// Add UIAlertAction in UIAlertController
optionMenuController.addAction(addAction)
optionMenuController.addAction(saveAction)
optionMenuController.addAction(deleteAction)
optionMenuController.addAction(cancelAction)
// Present UIAlertController with Action Sheet
self.present(optionMenuController, animated: true, completion: nil)
}

2022 Swift 5
func yourActionSheet() -> UIAlertController {
let alert = UIAlertController(title: "Your title",
message: nil,
preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Your action 1",
style: .default) { _ in
// onAction1()
})
alert.addAction(UIAlertAction(title: "Your action 2",
style: .default) { _ in
// onAction2()
})
alert.addAction(UIAlertAction(title: "Your cancel action",
style: .cancel) { _ in
// onCancel
})
return alert
}

SWIFT 4
WORKS ON IPHONE AND IPAD BOTH. ALSO ALLOWS ROTATION
LANDSCAPE
PORTRAIT
Code (tested)
let alert = UIAlertController()
let width: Int = Int(UIScreen.main.bounds.width - 100)
let viewAction = UIAlertAction(title: "View", style: .default , handler:{ (UIAlertAction)in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let orderDetailVC = storyboard.instantiateViewController(withIdentifier: "orderDetail") as! OrderDetailTableViewController
orderDetailVC.orderId = self.myDraftOrders[indexPath.row]["id"].intValue
self.navigationController?.pushViewController(orderDetailVC, animated: true)
})
viewAction.setValue(appGreenColor, forKey: "titleTextColor")
alert.addAction(viewAction)
let modifyAction = UIAlertAction(title: "Modify", style: .default, handler:{ (UIAlertAction)in
showAlert("Coming soon...")
})
modifyAction.setValue(appCyanColor, forKey: "titleTextColor")
alert.addAction(modifyAction)
let copyAction = UIAlertAction(title: "Copy", style: .default, handler:{ (UIAlertAction)in
self.copyOrder(orderId: self.myDraftOrders[indexPath.row]["id"].intValue)
})
copyAction.setValue(appBlueColor, forKey: "titleTextColor")
alert.addAction(copyAction)
alert.addAction(UIAlertAction(title: "Delete", style: .destructive , handler:{ (UIAlertAction)in
self.deleteOrder(orderId: self.myDraftOrders[indexPath.row]["id"].intValue, indexPath: indexPath)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:{ (UIAlertAction)in
print("User click Dismiss button")
}))
let popover = alert.popoverPresentationController
popover?.delegate = self
let cellT = tableView.cellForRow(at: indexPath)
popover?.sourceView = cellT
popover?.sourceRect = CGRect(x: width, y: 25, width: 100, height: 50)
present(alert, animated: true)

Swift :
The sample code given below works both on iPhone and iPad.
guard let viewRect = sender as? UIView else {
return
}
let cameraSettingsAlert = UIAlertController(title: NSLocalizedString("Please choose a course", comment: ""), message: NSLocalizedString("", comment: ""), preferredStyle: .ActionSheet)
cameraSettingsAlert.modalPresentationStyle = .Popover
let photoResolutionAction = UIAlertAction(title: NSLocalizedString("Photo Resolution", comment: ""), style: .Default) { action in
}
let cameraOrientationAction = UIAlertAction(title: NSLocalizedString("Camera Orientation", comment: ""), style: .Default) { action in
}
let flashModeAction = UIAlertAction(title: NSLocalizedString("Flash Mode", comment: ""), style: .Default) { action in
}
let timeStampOnPhotoAction = UIAlertAction(title: NSLocalizedString("Time Stamp on Photo", comment: ""), style: .Default) { action in
}
let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel) { action in
}
cameraSettingsAlert.addAction(cancel)
cameraSettingsAlert.addAction(cameraOrientationAction)
cameraSettingsAlert.addAction(flashModeAction)
cameraSettingsAlert.addAction(timeStampOnPhotoAction)
cameraSettingsAlert.addAction(photoResolutionAction)
if let presenter = cameraSettingsAlert.popoverPresentationController {
presenter.sourceView = viewRect;
presenter.sourceRect = viewRect.bounds;
}
presentViewController(cameraSettingsAlert, animated: true, completion: nil)

The Old Way: UIActionSheet
let actionSheet = UIActionSheet(title: "Takes the appearance of the bottom bar if specified; otherwise, same as UIActionSheetStyleDefault.", delegate: self, cancelButtonTitle: "Cancel", destructiveButtonTitle: "Destroy", otherButtonTitles: "OK")
actionSheet.actionSheetStyle = .Default
actionSheet.showInView(self.view)
// MARK: UIActionSheetDelegate
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
switch buttonIndex {
...
}
}
The New Way: UIAlertController
let alertController = UIAlertController(title: nil, message: "Takes the appearance of the bottom bar if specified; otherwise, same as UIActionSheetStyleDefault.", preferredStyle: .ActionSheet)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
// ...
}
alertController.addAction(OKAction)
let destroyAction = UIAlertAction(title: "Destroy", style: .Destructive) { (action) in
println(action)
}
alertController.addAction(destroyAction)
self.presentViewController(alertController, animated: true) {
// ...
}

Swift 3
For displaying UIAlertController from UIBarButtonItem on iPad
let alert = UIAlertController(title: "Title", message: "Please Select an Option", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Approve", style: .default , handler:{ (UIAlertAction)in
print("User click Approve button")
}))
alert.addAction(UIAlertAction(title: "Edit", style: .default , handler:{ (UIAlertAction)in
print("User click Edit button")
}))
alert.addAction(UIAlertAction(title: "Delete", style: .destructive , handler:{ (UIAlertAction)in
print("User click Delete button")
}))
alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.cancel, handler:{ (UIAlertAction)in
print("User click Dismiss button")
}))
if let presenter = alert.popoverPresentationController {
presenter.barButtonItem = sender
}
self.present(alert, animated: true, completion: {
print("completion block")
})

swift4 (tested)
let alertController = UIAlertController(title: "Select Photo", message: "Select atleast one photo", preferredStyle: .actionSheet)
let action1 = UIAlertAction(title: "From Photo", style: .default) { (action) in
print("Default is pressed.....")
}
let action2 = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
print("Cancel is pressed......")
}
let action3 = UIAlertAction(title: "Click new", style: .default) { (action) in
print("Destructive is pressed....")
}
alertController.addAction(action1)
alertController.addAction(action2)
alertController.addAction(action3)
self.present(alertController, animated: true, completion: nil)
}

Code for adding alerts to actionsheet in swift4
*That means when we click actionsheet values(like edit/ delete..so on) it shows
an alert option that is set with Yes or No option*
class ViewController: UIViewController
{
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func action_sheet1(_ sender: Any) {
let action_sheet1 = UIAlertController(title: "Hi Bro", message: "Please Select an Option: ", preferredStyle: .actionSheet)
action_sheet1.addAction(UIAlertAction(title: "Approve", style: .default , handler:{ (alert: UIAlertAction!) -> Void in
print("User click Approve button")
let alert = UIAlertController(title: "Approve", message: "Would you like to approve the file ", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}))
action_sheet1.addAction(UIAlertAction(title: "Edit", style: .default , handler:{ (alert: UIAlertAction!) -> Void in
print("User click Edit button")
let alert = UIAlertController(title: "Edit", message: "Would you like to edit the file ", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}))
action_sheet1.addAction(UIAlertAction(title: "Delete", style: .destructive , handler: { (alert: UIAlertAction!) -> Void in
print("User click Delete button")
let alert = UIAlertController(title: "Delete", message: "Would you like to delete the file permenently?", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}))
action_sheet1.addAction(UIAlertAction(title: "cancel", style: .cancel, handler:{ (alert: UIAlertAction!) -> Void in
print("User click cancel button")
let alert = UIAlertController(title: "Cancel", message: "Would you like to cancel?", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}))
self.present(action_sheet1, animated: true, completion: {
print("completion block")
})
}
}

Useful to populate dynamic actions list, and listen to selected action:
var categories = ["Science", "History", "Industry", "Agriculture"]
var handlerSelectedCategory: ((Int) -> ())?
func prepareActions(for title: String, index: Int) -> UIAlertAction {
let alertAction = UIAlertAction(title: title, style: .default) { (action) in
self.handlerSelectedCategory?(index)
}
return alertAction
}
#objc func presentActions() {
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
// add dymamic options
for (index, element) in self.categories.enumerated() {
optionMenu.addAction(prepareActions(for: element, index: index))
}
// cancel
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive)
optionMenu.addAction(cancelAction)
handlerSelectedCategory = { index in
print(index, self.categories[index])
}
self.present(optionMenu, animated: true, completion: nil)
}

You can use following code for Alert and ActionSheet in Swift 4:
#IBAction func alert_act(_ sender: Any) {
do {
let alert = UIAlertController(title: "Alert", message: "Would you like to continue learning?", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.default, handler: nil))
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
#IBAction func action_sheet1(_ sender: Any) {
let action_sheet1 = UIAlertController(title: nil, message: "Alert message.", preferredStyle: .actionSheet)
let defaultAction = UIAlertAction(title: "Default", style: .default, handler: nil)
let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
action_sheet1.addAction(defaultAction)
action_sheet1.addAction(deleteAction)
action_sheet1.addAction(cancelAction)
self.present(action_sheet1, animated: true, completion: nil)
}

Swift 5+
Very Simple and Smooth way just call this function and Boommmmmm!!!!!!!
let IPAD = UIDevice.current.userInterfaceIdiom == .pad
//Mark:- Choose Image Method
func funcMyActionSheet() {
var myActionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.actionSheet)
myActionSheet.view.tintColor = UIColor.black
let galleryAction = UIAlertAction(title: "Gallery".localizableString(language: Defaults.selectedLanguageCode), style: .default, handler: {
(alert: UIAlertAction!) -> Void in
self.openGallary()
})
let cmaeraAction = UIAlertAction(title: "Camera".localizableString(language: Defaults.selectedLanguageCode), style: .default, handler: {
(alert: UIAlertAction!) -> Void in
self.openCamera()
})
let cancelAction = UIAlertAction(title: "Cancel".localizableString(language: Defaults.selectedLanguageCode), style: .cancel, handler: {
(alert: UIAlertAction!) -> Void in
})
if IPAD {
//In iPad Change Rect to position Popover
myActionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.alert)
}
myActionSheet.addAction(galleryAction)
myActionSheet.addAction(cmaeraAction)
myActionSheet.addAction(cancelAction)
print("Action Sheet call")
self.present(myActionSheet, animated: true, completion: nil)
}

You can use following code for open actionSheet in Swift:
let alert = UIAlertController(title: enter your title, message: "Enter your messgage. ", preferredStyle: UIAlertControllerStyle.Alert)
alert.addTextFieldWithConfigurationHandler(configurationTextField)
alert.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Cancel, handler:{ (UIAlertAction)in
print("User click Cancel button")
}))
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler:{ (UIAlertAction)in
print("User click Ok button")
}))
self.presentViewController(alert, animated: true, completion: {
print("completion block")
})

Related

Warning - Attempt to present UIAlertController null in Swift

I have an UIAlertController running in my project which is connected through UIButton.My code works ok.But,Everytime when I pressed the button Xcode console printing an alert as below and I went through all the similar question been asked in stackOverflow but no answer.Attempt to present UIAlertController on UIViewController whose view is not in the window hierarchy
2016-10-03 19:14:35.854 xxxxxx[85186:7214348] Warning: Attempt to present<UIAlertController: 0x7f8d99450820> on <yyyyyyy.ViewController: 0x7f8d9a025200> which is already presenting (null)
My Code Below:
override func viewDidLoad() {
super.viewDidLoad()
self.moreButton.frame = CGRect(x:view.frame.width / 2, y: view.frame.height / 2, width: 100, height: 40)
moreButton.center = view.center
moreButton.backgroundColor = UIColor.darkText.withAlphaComponent(0.4)
moreButton.layer.masksToBounds = true
moreButton.setTitle("More", for: UIControlState())
moreButton.setTitleColor(UIColor.white, for: UIControlState())
moreButton.showsTouchWhenHighlighted = true
moreButton.layer.cornerRadius = 5.0
moreButton.addTarget(self, action: #selector(ViewController.moreButtonAction(_:)), for: .allTouchEvents)
self.view.addSubview(self.moreButton)
}
func moreButtonAction(_ sender: UIButton) {
DispatchQueue.main.async(execute: {
let myAlert = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
myAlert.view.tintColor = UIColor.purple.withAlphaComponent(0.8)
let myAction_1 = UIAlertAction(title: " Title 1", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
})
let myAction_2 = UIAlertAction(title: " Title 2", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
})
let myAction_3 = UIAlertAction(title: " Title 3", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
})
let myAction_4 = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: {
(action: UIAlertAction!) in
})
myAlert.addAction(myAction_1)
myAlert.addAction(myAction_2)
myAlert.addAction(myAction_3)
myAlert.addAction(myAction_4)
self.present(myAlert, animated: true, completion: nil)
})
}
Thanks in Advance
The error is telling you that you are trying to present an alertController that is already active. You could check if your controller has an active alert otherwise show it. This will remove the warning. So basically move your self.present row with the following:
if !(self.navigationController?.visibleViewController?.isKind(of: UIAlertController.self))! {
self.present(myAlert, animated: true, completion: nil)
}
Replace your moreActionButton function with the following:
func moreButtonAction(_ sender: UIButton) {
let myAlert = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
myAlert.view.tintColor = UIColor.purple.withAlphaComponent(0.8)
let myAction_1 = UIAlertAction(title: " Title 1", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
})
let myAction_2 = UIAlertAction(title: " Title 2", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
})
let myAction_3 = UIAlertAction(title: " Title 3", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
print("3")
})
let myAction_4 = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: {
(action: UIAlertAction!) in
})
myAlert.addAction(myAction_1)
myAlert.addAction(myAction_2)
myAlert.addAction(myAction_3)
myAlert.addAction(myAction_4)
if !(self.navigationController?.visibleViewController?.isKind(of: UIAlertController.self))! {
self.present(myAlert, animated: true, completion: nil)
}
}

Change UIImage Picker Button Label Text

The default text on the button for a user to confirm a picture when using the .Camera option for the UIImagePicker is "Use Picture".
Is there any way to change this to some other string?
func chooseAlert(){
let alert = UIAlertController(title: "Upload Image", message: "Choose Source For Image.", preferredStyle: .ActionSheet)
let cameraAction = UIAlertAction(title: "Take Photo", style: .Default, handler: { (action:UIAlertAction) -> Void in
dispatch_async(dispatch_get_main_queue())
{
// self.performSelector(#selector(self.useCamera), withObject: nil, afterDelay: 1.0)
self.useCamera()
}
})
let cameraRollAction = UIAlertAction(title: "Use Photo", style: .Default, handler: { (action:UIAlertAction) -> Void in
dispatch_async(dispatch_get_main_queue())
{
self.useCameraRoll()
}
})
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel){
(action) in
print(action)
}
alert.addAction(cameraAction)
alert.addAction(cameraRollAction)
alert.addAction(cancelAction)
presentViewController(alert, animated: true, completion: nil)
}
In the IBAction of the Button call this function which will bring an alert on the screen. In the alert actions, change the title as per your wish. useCamera() and useCameraRoll() are user defined functions.

iOS 9, Swift 2.1 - Delete alert in vertical layout

I have a plain style alert that shows 2 buttons horizontally made with the following implementation and I'd like to know how I can make it like the attached image.
let alert = UIAlertController(title: "", message: "This item will be deleted", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil));
alert.addAction(UIAlertAction(title: "Delete", style: UIAlertActionStyle.Destructive, handler: {
alertAction in
self.deleteItem(sender)
}))
presentViewController(alert, animated: true, completion: nil);
Use this one :-
let alert = UIAlertController(title: "", message: "This item will be deleted", preferredStyle: .ActionSheet)
You can use the following for what u want to acheive
#IBAction func actionRecommend(sender: UIButton) {
let optionMenu = UIAlertController(title: nil, message: "Recommend Using", preferredStyle: .ActionSheet)
optionMenu.view.tintColor = primaryDarkColor
let deleteAction = UIAlertAction(title: "Facebook", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
print("File Facebook")
})
let saveAction = UIAlertAction(title: "Contacts", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
print("File toContacts")
// self.performSegueWithIdentifier("toContacts", sender: nil)
})
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancelled")
})
optionMenu.addAction(deleteAction)
optionMenu.addAction(saveAction)
optionMenu.addAction(cancelAction)
self.presentViewController(optionMenu, animated: true, completion: nil)
}

Is it possible to have an AlertViewController be presented after another?

I want to have a UIAlertViewController that presents some text, and when you click "ok" it causes another UIAlertController to pop up and it will present the user with two options to choose from (go to main, restart game). this is the code I wrote and it brings up this error:
"2015-11-16 22:29:21.438 MemoryCardGameTest_01[1917:46708] Warning:
Attempt to present on
which is already
presenting (null)"
func showWinMessage() {
let userMessage = UIAlertController(title: "Victory! you win with... clicks \(ref2.clickCounter) and \(ref2.timeCounter) seconds", message: "", preferredStyle: UIAlertControllerStyle.Alert);
let action = UIAlertAction(title: "ok", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in
}
userMessage.addAction(action);
self.presentViewController(userMessage, animated: true, completion: nil);
println("victory achieved");
}
func showUserMessage(){
let newMessage = UIAlertController(title: "whatwouldyouliketodonext?", message: "", preferredStyle: UIAlertControllerStyle.Alert);
let goToUI = UIAlertAction(title: "goToUI", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in
println("gotoUI was clicked");
}
let playAgain = UIAlertAction(title: "PlayAgain", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in
println("playAgain was clicked");
}
newMessage.addAction(goToUI);
newMessage.addAction(playAgain);
self.presentViewController(newMessage, animated: true, completion: nil);
}
This roughly does what you want. Just make sure you don't call it in viewDidLoad as you can get an error like you mentioned. Try viewDidAppear or something.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let alertController = UIAlertController(title: "First message", message: "This is the first message", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
let alertController = UIAlertController(title: "Second message", message: "This is the second message", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
// ...
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) {
// ...
}
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) {
// ...
}
}
Essentially I just set the second view to appear in OKAction of the first alertController.

How to add an action to a UIAlertView button using Swift iOS

I want to add another button other than the "OK" button which should just dismiss the alert.
I want the other button to call a certain function.
var logInErrorAlert: UIAlertView = UIAlertView()
logInErrorAlert.title = "Ooops"
logInErrorAlert.message = "Unable to log in."
logInErrorAlert.addButtonWithTitle("Ok")
How do I add another button to this alert, and then allow it to call a function once clicks so lets say we want the new button to call:
retry()
The Swifty way is to use the new UIAlertController and closures:
// Create the alert controller
let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)
// Create the actions
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) {
UIAlertAction in
NSLog("OK Pressed")
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
}
// Add the actions
alertController.addAction(okAction)
alertController.addAction(cancelAction)
// Present the controller
self.presentViewController(alertController, animated: true, completion: nil)
Swift 3:
// Create the alert controller
let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)
// Create the actions
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
UIAlertAction in
NSLog("OK Pressed")
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
}
// Add the actions
alertController.addAction(okAction)
alertController.addAction(cancelAction)
// Present the controller
self.present(alertController, animated: true, completion: nil)
func showAlertAction(title: String, message: String){
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in
print("Action")
}))
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
UIAlertViews use a delegate to communicate with you, the client.
You add a second button, and you create an object to receive the delegate messages from the view:
class LogInErrorDelegate : UIAlertViewDelegate {
init {}
// not sure of the prototype of this, you should look it up
func alertView(view :UIAlertView, clickedButtonAtIndex :Integer) -> Void {
switch clickedButtonAtIndex {
case 0:
userClickedOK() // er something
case 1:
userClickedRetry()
/* Don't use "retry" as a function name, it's a reserved word */
default:
userClickedRetry()
}
}
/* implement rest of the delegate */
}
logInErrorAlert.addButtonWithTitle("Retry")
var myErrorDelegate = LogInErrorDelegate()
logInErrorAlert.delegate = myErrorDelegate
Swift 5+
let alert = UIAlertController(title: "Cart!", message: "Are you sure want to remove order details?", preferredStyle: .alert)
// Create the actions
let okAction = UIAlertAction(title: "YES", style:
UIAlertAction.Style.default) {
UIAlertAction in
print("Yes Pressed")
}
let cancelAction = UIAlertAction(title: "CANCEL", style:
UIAlertAction.Style.cancel) {
UIAlertAction in
print("Cancel Pressed")
}
// Add the actions
alert.addAction(okAction)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
OR
let alert = UIAlertController(title: "Alert!", message: "Are you sure want to remove your request?", preferredStyle: .alert)
// Create the actions
let okAction = UIAlertAction(title: "YES", style: .destructive) {
_ in
print("Yes Pressed")
self.funRemoveRequest(requestID: (self.requestStatusModel?.data?[sender.tag].id)!)
}
let cancelAction = UIAlertAction(title: "CANCEL", style: .cancel) {
_ in
print("Cancel Pressed")
}
// Add the actions
alert.addAction(okAction)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
Swift 4 Update
// Create the alert controller
let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)
// Create the actions
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
UIAlertAction in
NSLog("OK Pressed")
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
}
// Add the actions
alertController.addAction(okAction)
alertController.addAction(cancelAction)
// Present the controller
self.present(alertController, animated: true, completion: nil)
based on swift:
let alertCtr = UIAlertController(title:"Title", message:"Message", preferredStyle: .Alert)
let Cancel = AlertAction(title:"remove", style: .Default, handler: {(UIAlertAction) -> Void in })
let Remove = UIAlertAction(title:"remove", style: .Destructive, handler:{(UIAlertAction)-> Void
inself.colorLabel.hidden = true
})
alertCtr.addAction(Cancel)
alertCtr.addAction(Remove)
self.presentViewController(alertCtr, animated:true, completion:nil)}
Swift 3.0 Version of Jake's Answer
// Create the alert controller
let alertController = UIAlertController(title: "Alert!", message: "There is no items for the current user", preferredStyle: .alert)
// Create the actions
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
UIAlertAction in
NSLog("OK Pressed")
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
}
// Add the actions
alertController.addAction(okAction)
alertController.addAction(cancelAction)
// Present the controller
self.present(alertController, animated: true, completion: nil)
See my code:
#IBAction func foundclicked(sender: AnyObject) {
if (amountTF.text.isEmpty)
{
let alert = UIAlertView(title: "Oops! Empty Field", message: "Please enter the amount", delegate: nil, cancelButtonTitle: "OK")
alert.show()
}
else {
var alertController = UIAlertController(title: "Confirm Bid Amount", message: "Final Bid Amount : "+amountTF.text , preferredStyle: .Alert)
var okAction = UIAlertAction(title: "Confirm", style: UIAlertActionStyle.Default) {
UIAlertAction in
JHProgressHUD.sharedHUD.loaderColor = UIColor.redColor()
JHProgressHUD.sharedHUD.showInView(self.view, withHeader: "Amount registering" , andFooter: "Loading")
}
var cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) {
UIAlertAction in
alertController .removeFromParentViewController()
}
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
this is for swift 4.2, 5 and 5+
let alert = UIAlertController(title: "ooops!", message: "Unable to login", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)

Resources