UIAlertController: How to make the right button bolded? - ios

When I run the following code, the Yes button is always on the left side, how can I change it to right side and keep it bolded?
func showInAppPurchaseAlert() {
let alertController = UIAlertController.init(title: "Upgrade?", message: "Do you want to upgrade to pro version?", preferredStyle: .alert)
alertController.addAction(UIAlertAction.init(title: "No", style: .default, handler: { action in
self.dismiss(animated: true, completion: nil)
}))
let actionUpgrade = UIAlertAction.init(title: "Yes", style: .cancel, handler: { action in
self.upgradeToPro()
})
alertController.addAction(actionUpgrade)
alertController.preferredAction = actionUpgrade
self.present(alertController, animated: true, completion: nil)
}

The .default style will always have the right side, and the .cancel style the bold text. In order for you to change that, you have to set the preferredAction like you did in your code, but the problem was that you were using .cancel on your "Yes" action, which you wanted on the right side and your "No" action to .default. I tried your code, and this version works for me with your requirements.
func showInAppPurchaseAlert() {
let alertController = UIAlertController.init(title: "Upgrade?", message: "Do you want to upgrade to pro version?", preferredStyle: .alert)
alertController.addAction(UIAlertAction.init(title: "No", style: .cancel, handler: { action in
self.dismiss(animated: true, completion: nil)
}))
let actionUpgrade = UIAlertAction.init(title: "Yes", style: .default, handler: { action in
self.upgradeToPro()
})
alertController.addAction(actionUpgrade)
alertController.preferredAction = actionUpgrade
self.present(alertController, animated: true, completion: nil)
}

Pass .default for style:, it will use the cancel button look and feel.

Related

Why my alert can’t execute block and can’t dismiss?

I create an alert with UIAlertController and add some action in it. But when I touch button on it and, nothing changed. (Include cancel button) so I can only restart this application can solve this question.
let alert = UIAlertController(title: “my alert”, message: “some message...”, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: “button1”, style: .default, handler: { (_) in
print(“button 1 up inside”)
}))
alert.addAction(UIAlertAction(title: “button2”, style: .default, handler: { (_) in
print(“button 2 up inside”)
}))
alert.addAction(UIAlertAction(title: “cancel”, style: .cancel, handler: { (_) in
}))
self.present(alert, animated: true, completion: nil)
Xcode 10 built.
I had a similar problem in an app using the Sprite Kit. Here was the solution:
let connectActionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
connectActionSheet.addAction(UIAlertAction(title: "Button1", style: .default, handler: { (action:UIAlertAction) in
//Code if this button is pressed
}))
connectActionSheet.addAction(UIAlertAction(title: "Button2", style: .default, handler: { (action:UIAlertAction) in
//Code if button2 is pressed
}))
connectActionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let vc = self.view?.window?.rootViewController
if vc?.presentedViewController == nil {
vc?.present(connectActionSheet, animated: true, completion: nil)
}
The last 4 lines were what made it worked. I hope this helps you.
Thanks a lot! My view controller can’t close this alert because these code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
}

UIAlertController have different DOM structure in iPhone and iPad

I am showing UIAlertController in iOS and same code executes for iPhone and iPad. So can anyone help with this. As I google but didn't find any thing to justify this. Below is the code I have used:-
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let okAction = UIAlertAction(title: "Button.Ok".localizedValue(), style: .destructive, handler: { _ in
})
let cancelAction = UIAlertAction(title: "Button.Cancel".localizedValue(), style: .default, handler: { _ in
alert.dismiss(animated: true, completion: nil)
})
alert.accessibilityLabel = self.viewModel.deleteUserConfirmationAccessibilityId()
alert.addAction(okAction)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
So the problem is this:-
iPhone : "Remove all saved" text come under UIAView of the DOM Structure when doing automation testing for the UIAlertController in iPhone.
iPad : "Remove all saved" text come under UIView of the DOM Structure when doing automation testing for the UIAlertController in iPad.
So why difference is coming in UIAlertController structure as iPhone iPad showing UIView and iPhone UIAView for the same code.
You have to add popoverpresentation controller for ipad. Please see below code
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let okAction = UIAlertAction(title: "Button.Ok".localizedValue(), style: .destructive, handler: { _ in
})
let cancelAction = UIAlertAction(title: "Button.Cancel".localizedValue(), style: .default, handler: { _ in
alert.dismiss(animated: true, completion: nil)
})
alert.accessibilityLabel =
self.viewModel.deleteUserConfirmationAccessibilityId()
alert.addAction(okAction)
alert.addAction(cancelAction)
//self.present(alert, animated: true, completion: nil)
if(UIDevice.current.userInterfaceIdiom == .pad){
// for iPAD support:
alert.popoverPresentationController?.sourceView = self.view
alert.popoverPresentationController?.sourceRect = CGRect(x:self.view.bounds.width / 2.0, y:150, width:1.0, height:1.0)
self.present(actionSheet, animated: true, completion: nil)
}else{
// for iPHONE support:
let rootViewController: UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!
rootViewController.present(alert, animated: true, completion: nil)
}

How to change UIAlertAction font or show UIAlertActionStyle.cancel style ActionButton on second position?

I don't want to change UILabel.appearance as it will apply to all labels.
How I can show UIAlertController that will look like below image?
Need to show bold button in the second position.
By default, when I am setting UIAlertActionStyle.cancel it shows it on the Confirm button in the first position.
It looks like this now:
I did some research but I didn't find any solution.
Swift 4.2/Swift 5
You need to set preferred action method,
//Create alertController
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
//Create and add the Confirm action
let confirmAction = UIAlertAction(title: "Confirm", style: .default, handler: { (action) -> Void in
//Do Something here...
})
alert.addAction(confirmAction)
//Create and add the Cancel action
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) -> Void in
//Do Something here...
})
alert.addAction(cancelAction)
// Set Preferred Action method
alert.preferredAction = confirmAction
self.present(alert, animated: true, completion: nil)
The output will be,
You need to add them to the alertView in the right order! If you want the order to change just add the confirm button second!
alert.addAction(cancelAction)
alert.addAction(confirmAction)
Instead of:
alert.addAction(confirmAction)
alert.addAction(cancelAction)
Sure, you can. Try this
let alertView = UIAlertController(
title: "Home",
message: "Are you sure for delete Reminder",
preferredStyle: .alert)
alertView.view.tintColor = .green
let confirmAction = UIAlertAction(title: "Confirm", style: .cancel) { (_) in
// Do confirm
}
alertView.addAction(confirmAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .default) { (_) in
// Do cancel
}
alertView.addAction(cancelAction)
self.present(alertView, animated: true, completion: nil)

Swift how to implement the buttons that appear at the bottom when you want to something in a lot of apps

I want to implement this following buttons.Which library should i use for this?
You must use UIKit standard framework, using UIAlertController with UIActionSheet style will work for you
Example Code
let alertController:UIAlertController = UIAlertController.init(title: "Is this right!",message:"Bla Bla Bla?", preferredStyle:.actionSheet)
alertController.view.tintColor = self.saveProfileButton.titleLabel?.tintColor
alertController.addAction(UIAlertAction.init(title: "No", style:.default, handler: { (alertAction) in
//here add your code to handle No action
}))
alertController.addAction(UIAlertAction.init(title: "Yes", style:.default, handler: { (alertAction) in
//here add your code to handle YES action
}))
alertController.addAction(UIAlertAction.init(title: "Cancel", style:.destructive, handler: nil))
self.present(alertController, animated: true, completion: nil)

Trying to present 2 UIAlertControllers back to back

I have a UIAlertController in which the options are populated from an array and are presented to the user. The user then selects an option from the alert. After this, I have a separate alert that provides the user with a confirmation message that has an okay button.
myAlert.addAction(UIAlertAction.init(title: item, style: .Default, handler: {
(UIAlertAction) in
self.chosenBusiness.append(businessNameData[item]!)
}))
self.presentViewController(myAlert, animated: true, completion: nil)
The code above gathers the data from the array and pushes it into actions in myAlert. The code above is inside of a for loop.
After this I use a function to retrieve the topmost view controller, and then push the next alert.
let top = topMostController()
let alertController = UIAlertController(title: "Location pinned", message: "You've successfully pinned this location, good work!", preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) {
(result : UIAlertAction) -> Void in
print("OK")
}
alertController.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
top.presentViewController(alertController, animated: true, completion: {
_ in
})
The error I receive is:
Attempting to load the view of a view controller while it is
deallocating and is not allowed and may result in undefined behavior.
UIAlertController: 0x1535b1cd0.
Can someone help me with this?
I think this is what you are looking for. The second must be called with the dismissal action of the first. Also, anytime you work with UI, It is safer to use dispatch_async(dispatch_get_main_queue()) {
\\code }
than not if you are not positive you are currently on the main queue.
let firstAlertController = UIAlertController(title: "First", message: "This is the first message.", preferredStyle: UIAlertControllerStyle.Alert)
let secondAlertController = UIAlertController(title: "Second", message: "This is the second message.", preferredStyle: UIAlertControllerStyle.Alert)
let secondDismissAction = UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, completion: nil)
secondAlertController.addAction(secondDismissAction)
let firstDismissAction = UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default) {
UIAlertAction in
dispatch_async(dispatch_get_main_queue()) {
self.presentViewController(secondAlertController, animated: true, handler: nil)
}
}
firstAlertController.addAction(firstDismissAction)
self.presentViewController(firstAlertController, animated: true, completion: nil)

Resources