Creating a pop up dialog alert - swift

I'm trying to create a popup uialert sort of to create a confirmation box. I have a button in ViewControllerTwo and when pressed navigates back to ViewControllerOne, however I want to create a popup message that asks to confirm (Yes or No) if I really want to navigate to ViewControllerOne. If yes it goes backs to ViewOne, if no it stays on the ViewTwo. How do I do this?

#IBAction func showAlertTapped(sender: AnyObject) {
//Create the AlertController
let myAlertController: UIAlertController = UIAlertController(title: "Hey..!", message: "Are You sure to Do some stuff??", preferredStyle: .Alert)
//Create and add the Cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
//Do some stuff
}
myAlertController.addAction(cancelAction)
//Create and an option action
let nextAction: UIAlertAction = UIAlertAction(title: "Next", style: .Default) { action -> Void in
let mainStoryboard = UIStoryboard(name: "Storyboard", bundle: NSBundle.mainBundle())
let vc : UIViewController = mainStoryboard.instantiateViewControllerWithIdentifier("vcMainLogin") as UIViewController
self.presentViewController(vc, animated: true, completion: nil)
}
myAlertController.addAction(nextAction)
//Present the AlertController
self.presentViewController(myAlertController, animated: true, completion: nil)
}

Related

Segue to another storyboard without using Storyboard Reference?

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)
}

segue/push to different view controller from IBAction function?

I am trying to push to the next viewcontroller programatically, such that I can save data in core data and then push to the next view controller. Basically when I tap a button with an IBAction, it will do all this. However, I am getting a thread 1 SIGABRT error whenever I use this code in my IBAction func:
#IBAction func onPlusTapped(){
let alert = UIAlertController(title: "New Course", message: nil, preferredStyle: .alert)
alert.addTextField { (textField) in
textField.placeholder = "Course"
}
let action = UIAlertAction(title: "New", style: .default){ (_) in
let course = alert.textFields!.first?.text!
print(course)
let coursy = Course(context: PersistenceService.context)
coursy.name = course
PersistenceService.saveContext()
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
// jump to next view controller
segway()
}
func segway(){
let storyBoard: UIStoryboard = UIStoryboard(name: "viewcontroller", bundle: nil)
let balanceViewController = storyBoard.instantiateViewController(withIdentifier: "viewcontroller") as! ViewController
self.present(balanceViewController, animated: true, completion: nil)
}
}
If you want to jump to your next viewController once Course saved, you have to call the func segway() in the UIAlertAction completion block.
Example:
let action = UIAlertAction(title: "New", style: .default){ (_) in
let course = alert.textFields!.first?.text!
print(course)
let coursy = Course(context: PersistenceService.context)
coursy.name = course
PersistenceService.saveContext()
// jump to next view controller
segway()
}
Also double check your storyboard name and balanceViewController's identifier is "viewcontroller".
Why are you jumping segway() and present alert at the same time? shouldn't you put segway() inside your alert action?
Please see the following code.
#IBAction func onPlusTapped() {
let alert = UIAlertController(title: "New Course", message: nil, preferredStyle: .alert)
alert.addTextField { (textField) in
textField.placeholder = "Course"
}
let action = UIAlertAction(title: "New", style: .default){ (_) in
let course = alert.textFields!.first?.text!
print(course)
let coursy = Course(context: PersistenceService.context)
coursy.name = course
PersistenceService.saveContext()
// jump to next view controller
segway()
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
func segway() {
let storyBoard: UIStoryboard = UIStoryboard(name: "viewcontroller", bundle: nil)
let balanceViewController = storyBoard.instantiateViewController(withIdentifier: "viewcontroller") as! ViewController
self.present(balanceViewController, animated: true, completion: nil)
}
}
Hope this help!

Open a new view controller after login alert swift 2.0

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)
}

How to navigate ViewController when clicking button in alertView

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 :)

How do we create and dismiss an UIAlertController without user input? (Swift)

I've been looking up a lot of tutorials on UIAlertController. Thus far, the way I found was to activate a UIAlertController by linking it to a button or label and then call a IBAction.
I tried to replicate the code to automatically pop an alert when user enters the app (I wanted to ask the user if they want to go through the tutorial). However, I keep getting the error:
Warning: Attempt to present UIAlertController on MainViewController whose view is not in the window hierarchy!
Then I tried to add the UIAlertController to the MainViewController via addChildViewController and addSubview. However, I get the error:
Application tried to present modally an active controller
I figured that I cannot use the presentViewController function and commented it out.
The UIAlertController is displayed BUT when I tried to click on the cancel or the never button, this error occurs.
Trying to dismiss UIAlertController with unknown presenter.
I am really stumped. Can someone share what I am doing wrong? Thank you so much. Here is the code.
func displayTutorial() {
alertController = UIAlertController(title: NSLocalizedString("tutorialAlert", comment: ""), message: NSLocalizedString("tutorialMsg", comment: ""), preferredStyle: .ActionSheet)
self.addChildViewController(alertController)
self.view.addSubview(alertController.view)
alertController.didMoveToParentViewController(self)
alertController.view.frame.origin.x = self.view.frame.midX
alertController.view.frame.origin.y = self.view.frame.midY
//alertController.popoverPresentationController?.sourceView = self.view*/
let OkAction = UIAlertAction(title: NSLocalizedString("yesh", comment: ""), style: .Destructive) { (action) in
}
alertController.addAction(OkAction)
let cancelAction = UIAlertAction(title: NSLocalizedString("notNow", comment: ""), style: .Destructive) { (action) in
//println(action)
self.tutorial = 1
self.presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
alertController.addAction(cancelAction)
let neverAction = UIAlertAction(title: NSLocalizedString("never", comment: ""), style: .Cancel) { (action) in
self.tutorial = 1
}
alertController.addAction(neverAction)
//self.presentViewController(alertController, animated: false) {}
}
I found the solution. Apparently, I cannot call the UIAlertController from the func viewDidLoad. I must call the function from viewDidAppear. So my code now is
override func viewDidAppear(animated: Bool) {
if tutorial == 0 {
displayTutorial(self.view)
}
}
func displayTutorial(sender:AnyObject) {
let alertController = UIAlertController(title: NSLocalizedString("tutorialAlert", comment: ""), message: NSLocalizedString("tutorialMsg", comment: ""), preferredStyle: .ActionSheet)
let OkAction = UIAlertAction(title: NSLocalizedString("yesh", comment: ""), style: .Destructive) { (action) in
}
alertController.addAction(OkAction)
let cancelAction = UIAlertAction(title: NSLocalizedString("notNow", comment: ""), style: .Default) { (action) in
//println(action)
self.tutorial = 1
self.presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
alertController.addAction(cancelAction)
let neverAction = UIAlertAction(title: NSLocalizedString("never", comment: ""), style: .Cancel) { (action) in
self.tutorial = 1
}
alertController.addAction(neverAction)
self.presentViewController(alertController, animated: true, completion: nil)
if let pop = alertController.popoverPresentationController {
let v = sender as UIView
pop.sourceView = view
pop.sourceRect = v.bounds
}
}
Thanks to this posting: Warning: Attempt to present * on * whose view is not in the window hierarchy - swift
Below UIAlertController with extension would help you show alert with dynamic number of buttons with completion handler for selected index
extension UIViewController {
func displayAlertWith(message:String) {
displayAlertWith(message: message, buttons: ["Dismiss"]) { (index) in
}
}
func displayAlertWith(message:String, buttons:[String], completion:((_ index:Int) -> Void)!) -> Void {
displayAlertWithTitleFromVC(vc: self, title: Bundle.main.infoDictionary!["CFBundleDisplayName"] as! String, andMessage: message, buttons: buttons, completion: completion)
}
func displayAlertWithTitleFromVC(vc:UIViewController, title:String, andMessage message:String, buttons:[String], completion:((_ index:Int) -> Void)!) -> Void {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
for index in 0..<buttons.count {
let action = UIAlertAction(title: buttons[index], style: .default, handler: {
(alert: UIAlertAction!) in
if(completion != nil){
completion(index)
}
})
alertController.addAction(action)
}
DispatchQueue.main.async {
vc.present(alertController, animated: true, completion: nil)
}
}
}
If you need to auto dismiss the alert you can call dismiss on presented view controller after some delay.
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
vc.dismiss(animated: true, completion: nil)
}
Hope this might help you.