Search code examples
iosswift3uialertcontrolleruiactionsheet

Is there a way to call an alert controller from inside a current alert controller (or a textfield in an action sheet)? Xcode 8, Swift 3, IOS


Please help! Im a huge beginner. Im trying to get a picker view and a textfield into one alert controller. Apparently I can't add a picker view into an alert controller since IOS 8. Instead I need to use an action sheet with multiple actions. Why can't I use a default alert style? Because I need more than 2 actions and the default alert style apparently only permits a max of 2 actions. So, I need to use an action sheet. Only problem is I can't seem to find a way to put an editable textfield into an action sheet, to have multiple action options - instead of an editable textfield in my default alert style, with only two action options.

This is what I have so far, for my editable textfield in my default alert style, with only two options (OK and cancel):

@IBOutlet weak var TEXTTESTLabel: UILabel!

@IBAction func TEXTESTTapped(_ sender: UIButton) {
    print("TEXTTEST Button Tapped")
    openTEXTTESTAlert()
}


func openTEXTTESTAlert() {
    //Create Alert Controller
    let alert9 = UIAlertController (title: "Test Your Text:", message: nil, preferredStyle: UIAlertControllerStyle.alert)

    //Create Cancel Action
    let cancel9 = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil)

    alert9.addAction(cancel9)

    //Create OK Action
    let ok9 = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) { (action: UIAlertAction) in print("OK")
        let textfield = alert9.textFields?[0]
        print(textfield?.text!)
        self.TEXTTESTLabel.text = textfield?.text!
    }

    alert9.addAction(ok9)

    //Add Text Field
    alert9.addTextField { (textfield: UITextField) in
        textfield.placeholder = "TEXTTEST"
    }

    //Present Alert Controller
    self.present(alert9, animated:true, completion: nil)
}

//////////////////////////////////////////////////////////////////////////////////

Since this, I've gotten help to create two separate alert controllers but it looks and feels messy. It's set up so if I click button 2 the default alert style with a textfield will pop and insert text into a label. But, if i click button 1, AND THEN I click button 2, it will show an action sheet with 4 actions that put a word into that same label. This is what I have for that method:

@IBOutlet weak var TextLabel: UILabel!


var userWantsToShowAlert = false

@IBAction func yourNewButtonTapped(_ sender: UIButton) {
    userWantsToShowAlert = !userWantsToShowAlert
    print("User wants to show alert? \(userWantsToShowAlert)")
    //This is userWantsToShowAlert is false, it will change it to true. And if it is true, it will change it to false.
}

@IBAction func TextButtonTapped(_ sender: UIButton) {
    print("Text Button Tapped")
    if(userWantsToShowAlert){
        openTextAlert()
    }else{
        openActionSheetAlert()
    }


}

func openTextAlert() {
    //Create Alert Controller
    let alert9 = UIAlertController (title: "Whatever Text Your Heart Desires:", message: nil, preferredStyle: UIAlertControllerStyle.alert)

    //Create Cancel Action
    let cancel9 = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil)

    alert9.addAction(cancel9)

    //Create OK Action
    let ok9 = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) { (action: UIAlertAction) in print("OK")
        let textfield = alert9.textFields?[0]
        print(textfield?.text!)
        self.TextLabel.text = textfield?.text!
    }

    alert9.addAction(ok9)

    //Add Text Field
    alert9.addTextField { (textfield: UITextField) in
        textfield.placeholder = "Whatever text you want to enter"
    }

    //Present Alert Controller
    self.present(alert9, animated:true, completion: nil)
}

func openActionSheetAlert(){
    let alert9 = UIAlertController (title: "Whatever Text Your Heart Desires:", message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)

    //Create Cancel Action
    let cancel9 = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil)
    alert9.addAction(cancel9)


    let bt1 = UIAlertAction(title: "1", style: UIAlertActionStyle.default){
        (action) in self.TextLabel.text = "Word 1"}

    alert9.addAction(bt1)

    let bt2 = UIAlertAction(title: "2", style: UIAlertActionStyle.default){
        (action) in self.TextLabel.text = "Word 2"}

    alert9.addAction(bt2)


    let bt3 = UIAlertAction(title: "3", style: UIAlertActionStyle.default){
        (action) in self.TextLabel.text = "Word 3"}

    alert9.addAction(bt3)

    let bt4 = UIAlertAction(title: "4", style: UIAlertActionStyle.default){
        (action) in self.TextLabel.text = "Word 4"}
    alert9.addAction(bt4)

    alert9.popoverPresentationController?.sourceView = self.view
    alert9.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.size.width / 2.0, y: self.view.bounds.size.height / 4.0, width: 1.0, height: 1.0)
    self.present(alert9, animated:true, completion: nil)
}

I find that this method is confusing to the application user. If anyone has a different method to get a textfield into an action sheet (or even a separate alert controller imbedded in a current alert controller), I'd appreciate it VERY much! Thank you :)


Solution

  • I found the solution! I was wrong about having only 2 actions in the default alert style. How to scroll through actions in alert controller? Xcode 8, Swift 3, IOS