2014-06-29 25 views
22

Mam AlertController z polem tekstowym i dwoma przyciskami: CANCEL i SAVE. Jest to kod:Sprawdź UIAlertController TextField dla włączenia przycisku

@IBAction func addTherapy(sender: AnyObject) 
{ 
    let addAlertView = UIAlertController(title: "New Prescription", message: "Insert a name for this prescription", preferredStyle: UIAlertControllerStyle.Alert) 

    addAlertView.addAction(UIAlertAction(title: "Cancel", 
             style: UIAlertActionStyle.Default, 
             handler: nil)) 

    addAlertView.addAction(UIAlertAction(title: "Save", 
             style: UIAlertActionStyle.Default, 
             handler: nil)) 

    addAlertView.addTextFieldWithConfigurationHandler({textField in textField.placeholder = "Title"}) 


    self.presentViewController(addAlertView, animated: true, completion: nil) 


} 

Co chcę zrobić jest wdrożyć kontrolę pola tekstowego na wyłączenie przycisku ZAPISZ gdy pole tekstowe jest puste, podobnie jak obrazy Aplikacja iOS, gdy chcesz stworzyć NewAlbum. Czy ktoś może mi wyjaśnić, co mam robić?

Odpowiedz

23

Najpierw utworzę moduł alertcontroller z początkowo wyłączoną akcją składowania. Następnie, dodając pole tekstowe inculde, Powiadomienie, aby obserwować jego zmianę w procedurze obsługi i w tym selektorze, wystarczy przełączyć właściwość włączoną akcji zapisu.

Oto, co mówię:

//hold this reference in your class 
weak var AddAlertSaveAction: UIAlertAction? 

@IBAction func addTherapy(sender : AnyObject) { 

    //set up the alertcontroller 
    let title = NSLocalizedString("New Prescription", comment: "") 
    let message = NSLocalizedString("Insert a name for this prescription.", comment: "") 
    let cancelButtonTitle = NSLocalizedString("Cancel", comment: "") 
    let otherButtonTitle = NSLocalizedString("Save", comment: "") 

    let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) 

    // Add the text field with handler 
    alertController.addTextFieldWithConfigurationHandler { textField in 
     //listen for changes 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleTextFieldTextDidChangeNotification:", name: UITextFieldTextDidChangeNotification, object: textField) 
    } 


    func removeTextFieldObserver() { 
     NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: alertController.textFields[0]) 
    } 

    // Create the actions. 
    let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .Cancel) { action in 
     NSLog("Cancel Button Pressed") 
     removeTextFieldObserver() 
    } 

    let otherAction = UIAlertAction(title: otherButtonTitle, style: .Default) { action in 
     NSLog("Save Button Pressed") 
     removeTextFieldObserver() 
    } 

    // disable the 'save' button (otherAction) initially 
    otherAction.enabled = false 

    // save the other action to toggle the enabled/disabled state when the text changed. 
    AddAlertSaveAction = otherAction 

    // Add the actions. 
    alertController.addAction(cancelAction) 
    alertController.addAction(otherAction) 

    presentViewController(alertController, animated: true, completion: nil) 
} 

    //handler 
func handleTextFieldTextDidChangeNotification(notification: NSNotification) { 
    let textField = notification.object as UITextField 

    // Enforce a minimum length of >= 1 for secure text alerts. 
    AddAlertSaveAction!.enabled = textField.text.utf16count >= 1 
} 

Robię to w innym projekcie - Mam tego wzorca bezpośrednio z przykładów jabłek. Mają bardzo dobry przykład projekt przedstawiający niektóre z tych wzorców w przykładach UICatalog: https://developer.apple.com/library/content/samplecode/UICatalog/Introduction/Intro.html

+0

Bardzo mi pomagasz! Dziękuję Ci bardzo! – Andorath

+4

Używanie powiadomienia jest zbyt ciężkie (i niewiarygodne, i zbyt wiele pracy). Dlatego są delegaci pól tekstowych i akcje. Zobacz moją odpowiedź tutaj: http://stackoverflow.com/a/25628065/341994 – matt

+1

Odpowiedź Matta jest lepsza – LastMove

41

Jest znacznie prostszy sposób, bez użycia centrum powiadamiania, w SWIFT:

Swift 3 na odpowiedź od Sourabh Sharma:

weak var actionToEnable : UIAlertAction? 

func showAlert() 
{ 
    let titleStr = "title" 
    let messageStr = "message" 

    let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.alert) 

    let placeholderStr = "placeholder" 

    alert.addTextField(configurationHandler: {(textField: UITextField) in 
     textField.placeholder = placeholderStr 
     textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .editingChanged) 
    }) 

    let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (_) -> Void in 

    }) 

    let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { (_) -> Void in 
     let textfield = alert.textFields!.first! 

     //Do what you want with the textfield! 
    }) 

    alert.addAction(cancel) 
    alert.addAction(action) 

    self.actionToEnable = action 
    action.isEnabled = false 
    self.present(alert, animated: true, completion: nil) 
} 

func textChanged(_ sender:UITextField) { 
    self.actionToEnable?.isEnabled = (sender.text! == "Validation") 
} 

Swift 2.0:

weak var actionToEnable : UIAlertAction? 

func showAlert() 
{ 
    let titleStr = "title" 
    let messageStr = "message" 

    let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert) 

    let placeholderStr = "placeholder" 

    alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in 
     textField.placeholder = placeholderStr 
     textField.addTarget(self, action: #selector(self.textChanged(_:)), forControlEvents: .EditingChanged) 
    }) 

    let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (_) -> Void in 

    }) 

    let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (_) -> Void in 
     let textfield = alert.textFields!.first! 

     //Do what you want with the textfield! 
    }) 

    alert.addAction(cancel) 
    alert.addAction(action) 

    self.actionToEnable = action 
    action.enabled = false 
    self.presentViewController(alert, animated: true, completion: nil) 
} 

func textChanged(sender:UITextField) { 
    self.actionToEnable?.enabled = (sender.text! == "Validation") 
} 
+2

To powinna być poprawna odpowiedź – CodyMace

+1

Na kodzie Swift 3, brak definicji "actionToEnable' –

+0

Wspaniałe ..! Fajna odpowiedź –

3

Swift 3.0 Aktualizacja Rozwiązanie podane przez @spoek

func showAlert() 
    { 
     let titleStr = "title" 
     let messageStr = "message" 

     let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.alert) 

     let placeholderStr = "placeholder" 

     alert.addTextField(configurationHandler: {(textField: UITextField) in 
      textField.placeholder = placeholderStr 
      textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .editingChanged) 
     }) 

     let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (_) -> Void in 

     }) 

     let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { (_) -> Void in 
      let textfield = alert.textFields!.first! 

      //Do what you want with the textfield! 
     }) 

     alert.addAction(cancel) 
     alert.addAction(action) 

     self.actionToEnable = action 
     action.isEnabled = false 
     self.present(alert, animated: true, completion: nil) 
    } 

    func textChanged(_ sender:UITextField) { 
     self.actionToEnable?.isEnabled = (sender.text! == "Validation") 
    } 
+0

Naprawdę pomocna. Dzięki :) –

1

Zaimplementowałem podklasę UIAlertController do wygodnego dodawania pól tekstowych i związanych z nimi włączania i wyłączania przycisków. Podstawowa logika jest podobna do tej Sourabh Sharma, ale wszystko jest zawarte w tej podklasie dla porządku. To powinno być pomocne, jeśli twój projekt obejmuje wiele takich funkcji ostrzegania.

public class TextEnabledAlertController: UIAlertController { 
    private var textFieldActions = [UITextField: ((UITextField)->Void)]() 

    func addTextField(configurationHandler: ((UITextField) -> Void)? = nil, textChangeAction:((UITextField)->Void)?) { 
     super.addTextField(configurationHandler: { (textField) in 
     configurationHandler?(textField) 

     if let textChangeAction = textChangeAction { 
      self.textFieldActions[textField] = textChangeAction 
      textField.addTarget(self, action: #selector(self.textFieldChanged), for: .editingChanged) 

     } 
    }) 

} 

    @objc private func textFieldChanged(sender: UITextField) { 
    if let textChangeAction = textFieldActions[sender] { 
     textChangeAction(sender) 
    } 
    } 
} 

Aby go użyć, wystarczy dostarczyć blok textChangeAction podczas dodawania pól tekstowych:

alert.addTextField(configurationHandler: { (textField) in 
     textField.placeholder = "Your name" 
     textField.autocapitalizationType = .words 
    }) { (textField) in 
     saveAction.isEnabled = (textField.text?.characters.count ?? 0) > 0 
    } 

Pełen przykład patrz the git page.