This question already has answers here:
UIAlertController is Crashed (iPad)
(11 answers)
Closed 4 years ago.
Here is my code
let selectRoute = UIAlertController(title: "Select a Route", message: "Please select the route you want to create your trip on", preferredStyle: .actionSheet)
let route1 = UIAlertAction(title: "Route 1", style: .default) { (action) in
self.reminder()
self.routeID = 1
self.tableView.reloadData()
}
let route2 = UIAlertAction(title: "Route 2", style: .default) { (action) in
}
selectRoute.addAction(route1)
selectRoute.addAction(route2)
if let popoverPresentationController = selectRoute.popoverPresentationController {
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = self.view.bounds
}
self.present(selectRoute, animated: true, completion: nil)
When I run this, the actionSheet just appears just over the Navigation Controller really small, anyone know a fix?
On iPad the alert will be displayed as a popover using the UIPopoverPresentationController, it requires you define an anchor point for the presentation of the popover using either a sourceView and sourceRect or a barButtonItem.
To support iPad, include this code:
alertController.popoverPresentationController?.sourceView = self.view
alertController.popoverPresentationController?.sourceRect = self.myButton.frame
self.presentViewController(alertController, animated: true, completion: nil)
here is an example:
Suppose you have a button and you are going to show alert controller below of the button:
#IBOutlet weak var myBtn: UIButton!
let alertController = UIAlertController(title: "title :)", message:"message...", preferredStyle: .actionSheet)
let defaultAction = UIAlertAction(title: "cancel", style: .cancel, handler: nil)
let deleteAction = UIAlertAction(title: "delete", style: .destructive) { (action: UIAlertAction) in
//Do something
}
let addAction = UIAlertAction(title: "...", style: .default) { (action) in
//do something
}
alertController.addAction(addAction)
alertController.addAction(deleteAction)
alertController.addAction(defaultAction)
alertController.popoverPresentationController?.sourceRect = self.myBtn.frame
alertController.popoverPresentationController?.sourceView = self.view
self.present(alertController, animated: true, completion: nil)
If you are displaying the action sheet after the user makes a selection on a cell within a UITableView. you can use this code:
alertController.popoverPresentationController.sourceView = cell
alertController.popoverPresentationController.sourceRect = cell.bounds
Related
I have a button in my App which gives an alert when clicked, and only if the user clicks "OK" - I want to send them to another storyboard. Is it possible to do this in the ViewController? Without a storyboard reference? How will the code look like?
Based on the updated details from your comments, you will need to instantiate your viewController in your storyboard and perform the navigation manually like so:
let alert = UIAlertController(title: "Alert!", message: "Do the thing", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default) { (action) in
let storyboard = UIStoryboard(name: "Bussturen", bundle: nil)
let viewController = storyboard.instantiateViewController(identifier: "BussturenViewController") as! BussturenViewController
//Do any more setup you might need to do for your viewController before navigation
self.navigationController?.pushViewController(viewController, animated: true)
}
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
Please also note that this assumes that in the Identity Inspector in your storyboard you have your BussturenViewController set as "BussturenViewController"
Place the below code
// Your button tap function
#IBAction func buttonClickAction(_ sender: Any) {
let alert = UIAlertController(title: "", message: "Show me next view controller", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
self.displayNextViewController()
}))
alert.addAction(UIAlertAction(title: "NO", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// Function which loads next view controller
func displayNextViewController() {
let nextViewController = NextViewController() as UIViewController
self.navigationController?.pushViewController(nextViewController, animated: true)
}
You can customize the nextVC instantiation based on your requirement. Hope this helps for you!
by looking at the help from all the answers, I was able to find a solution:
func displayNextViewController() {
let storyBoard : UIStoryboard = UIStoryboard(name: "Bussturen", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "BussturenViewController") as! BussturenViewController
nextViewController.modalPresentationStyle = .fullScreen
self.present(nextViewController, animated:false, completion:nil)
}
#IBAction func bussturenTapped(_ sender: UIButton) {
let alert = UIAlertController(title: "", message: "Show me next view controller", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: {_ in self.displayNextViewController() }))
alert.addAction(UIAlertAction(title: "NO", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
This question already has answers here:
Unable to choose order of buttons in UIAlertController
(2 answers)
Closed 5 years ago.
I wanna show alert window by pressing on button. Usual thing. But I'm confused that I try to show button "Awesome" at first, but always "Cancel" button stay the first. How can I fix it?
let alert = UIAlertController(title: "Hello world", message: "Testing", preferredStyle: .alert)
let action = UIAlertAction(title: "Awesome", style: .default){(_) in print("Awesome")}
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alert.addTextField(configurationHandler: nil)
alert.addAction(action)
alert.addAction(cancel)
alert.actions.forEach( { (action) in print( action.title! ) } )
present(alert, animated: true, completion: nil)
Irregular order of buttons
Changing the order will not work as default position of cancel button is left.
Change the action style for cancel button type to UIAlertActionStyleDefault instead of UIAlertActionStyleCancel.
Try like this, it will work for you.
let alertController = UIAlertController(title: "", message: "", preferredStyle: UIAlertControllerStyle.alert)
let destructiveAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default) {
(result : UIAlertAction) -> Void in
}
let okAction = UIAlertAction(title: "Awesome", style: UIAlertActionStyle.default) {
(result : UIAlertAction) -> Void in
}
alertController.addAction(destructiveAction)
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
everyone I am making Alert from my AlertController, but I want after action button "OK" is pressed, open LoginController, how I can do that?I tried to do that just like below, but it's not working
AlertController:
class AlertController: NSObject {
class func showErrorWith(title:String? = nil, message:String? = nil, controller: UIViewController , complition:(() -> ())?){
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
// let storyboard = UIStoryboard(name: "Main", bundle: nil)
// let viewController = storyboard.instantiateViewController(withIdentifier :"LoginVC")
// self.present(viewController, animated: true)
//
}))
controller.present(alert, animated: true, completion: nil)
}
It's happen because you call self.present in this code self - It's kind of NSObject.
Just call controller.present(viewController, animated:true);
func ShowAlert(vc: UIViewController, title: String, message:String, affirmButton: String = "OK", cancelButton: String = "Cancel", onAffirmation: (Void) -> (Void) = { })
{
let alertView = UIAlertController(title: title, message: message, preferredStyle: .Alert)
alertView.addAction(UIAlertAction(title: affirmButton, style: UIAlertActionStyle.Default, handler:{(action) in
onAffirmation()
}))
alertView.addAction(UIAlertAction(title: cancelButton, style: UIAlertActionStyle.Default, handler: nil))
vc.presentViewController(alertView, animated: true, completion: nil)
}
I am trying to change view controller if the login is successful but I am unsure how to do this. This is what i have tried so far. Thanks in advance!
#IBAction func signinaction(sender: AnyObject) {
let user = self.usernamefield.text!
ref.authUser(emailfield.text, password: passwordfield.text, withCompletionBlock: { error, authData in
if error != nil
{
let alert = UIAlertController(title: "Error", message: "Enter Email and Password.", preferredStyle: UIAlertControllerStyle.Alert)
let action = UIAlertAction(title: "Ok", style: .Default, handler: nil)
alert.addAction(action)
self.presentViewController(alert, animated: true, completion: nil)
print("can not sign in")
}
else
{
let storyboard = UIStoryboard(name: "Main", bundle: nil);
let viewName:NSString = "NewView"
let vc = storyboard.instantiateViewControllerWithIdentifier(viewName as String) as! HomeViewController
let uid = authData.uid
print("Success with user: \(uid)")
let alert = UIAlertController(title: "Success", message: "Welcome \(user)", preferredStyle: UIAlertControllerStyle.Alert)
let action = UIAlertAction(title: "Ok", style: .Default, handler: nil)
alert.addAction(action)
self.navigationController?.pushViewController(vc as HomeViewController, animated: true)
}
})
}
Assuming that the view controller all of this is in is contained in a navigation controller, what you have should be working fine. Note, however that you're creating an alert you never show. My guess is that you want to display the success alert and then open the new view controller, something like:
let alert = UIAlertController(title: "Success", message: "Welcome \(user)", preferredStyle: UIAlertControllerStyle.Alert)
let action = UIAlertAction(title: "Ok", style: .Default) { _ in
self.navigationController?.pushViewController(vc, animated: true)
}
alert.addAction(action)
self.presentViewController(alert, animated: true, completion: nil)
If this still isn't working, I'd make sure the current view controller is actually displayed in a navigation controller.
Looks like you just need to add the navigation code inside of the alert action. Currently you have the handler parameter set to nil
this
let action = UIAlertAction(title: "Ok", style: .Default, handler: nil)
becomes this
let alertAction = UIAlertAction(title: "Ok", style: .Default) { (action) -> Void in
self.navigationController?.pushViewController(vc as HomeViewController, animated: true)
}
Given the code below, when I click the "Accept" button, it doesn't navigate to SecondViewController, it only shows a black screen. Any help appreciated.
let alertController = UIAlertController(title: tit!, message: "Book Now!", preferredStyle: .Alert)
let declineAction = UIAlertAction(title: "Decline", style: .Cancel, handler: nil)
alertController.addAction(declineAction)
let acceptAction = UIAlertAction(title: "Accept", style: .Default) { (_) -> Void in
let nv=SecondViewController()
self.presentViewController(nv, animated:true, completion:nil)
}
presentViewController(alertController, animated: true, completion: nil)
alertController.addAction(acceptAction)
To open any UIViewController just must instantiate it. And what you are doing is just creating the object of the class.
To do so:
let nv = self.storyboard!.instantiateViewControllerWithIdentifier("storyboardidentifier") as! SecondViewController
self.presentViewController(nv, animated:true, completion:nil)
This is open your UIViewController as wants!
Create a segue link from your current view controller to the SecondViewController and give it an identifier in the storyboard and you can use the following code
let alert = UIAlertController(title: "Options", message: "Book Now!", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Accept", style: UIAlertActionStyle.Default, handler: { (alertAction) -> Void in
self.performSegueWithIdentifier("FirstToSecond", sender: self)
}))
self.presentViewController(alert, animated: true, completion: nil)
Note: your first view controller will be the anchor.
If you have embedded your SecondViewController in a navigation controller and also want to pass the value, you can add the following
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "FirstToSecond" {
let nav = segue.destinationViewController as! UINavigationController
let svc = nav.viewControllers[0] as! SecondViewController
//svc.delegate = self //uncomment this if you need to set a delegate as well
svc.value = ""
}
}
This is using xCode 7 & Swift 2. Hope this helps :)