web-dev-qa-db-fra.com

Ajouter UIToolBar à tous les claviers (Swift)

J'essaie d'ajouter un UIToolBar personnalisé à tous mes claviers avec aussi peu de répétition. La façon dont je le fais actuellement me force à ajouter le code à tous mes viewDidLoads et à affecter le délégué de chaque champ de texte au viewController que j'utilise. J'ai essayé de créer ma propre sous-classe UIToolBar mais je constate que je ne peux pas vraiment le faire lorsque la cible de mes boutons "Terminé" et "Annuler" correspond à la vue autonome. Quelqu'un a-t-il des suggestions pour créer une barre d'outils facilement réutilisable? Merci d'avance. 

override func viewDidLoad() {
    super.viewDidLoad()

    var toolBar = UIToolbar()
    toolBar.barStyle = UIBarStyle.Default
    toolBar.translucent = true
    toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
    var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed")
    var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPressed")
    var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
    toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
    toolBar.userInteractionEnabled = true
    toolBar.sizeToFit()

    stateField.inputAccessoryView = toolBar
    stateField.delegate = self
15
Vivian

Grâce à la suggestion de Glorfindel et à l'exemple de code de ncerezo, j'ai résolu mon problème en utilisant des extensions. 

extension UIViewController: UITextFieldDelegate{
    func addToolBar(textField: UITextField){
        var toolBar = UIToolbar()
        toolBar.barStyle = UIBarStyle.Default
        toolBar.translucent = true
        toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
        var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed")
        var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPressed")
        var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
        toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
        toolBar.userInteractionEnabled = true
        toolBar.sizeToFit()

        textField.delegate = self
        textField.inputAccessoryView = toolBar
    }
    func donePressed(){
        view.endEditing(true)
    }
    func cancelPressed(){
        view.endEditing(true) // or do something
    }
}

Bien que je doive toujours appeler le code ci-dessous sur tous mes champs de texte. Je pense qu’il existe peut-être un meilleur moyen de ne pas avoir à appeler la fonction sur chaque textField, mais pour l’instant, cela est nettement plus réutilisable.

override func viewDidLoad() {
    super.viewDidLoad()
    addToolBar(addressField)
}
48
Vivian

équivalent de la version vivian dans Swift 3:

extension UIViewController: UITextFieldDelegate {
    func addToolBar(textField: UITextField) {
        let toolBar = UIToolbar()
        toolBar.barStyle = .default
        toolBar.isTranslucent = true
        toolBar.tintColor = UIColor(red: 76 / 255, green: 217 / 255, blue: 100 / 255, alpha: 1)
        let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(donePressed))
        let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelPressed))
        let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)


        toolBar.isUserInteractionEnabled = true
        toolBar.sizeToFit()

        textField.delegate = self
        textField.inputAccessoryView = toolBar
    }

    func donePressed() {
        view.endEditing(true)
    }

    func cancelPressed() {
        view.endEditing(true) // or do something
    }
}
14
alessioarsuffi

Pour Swift 4, vous pouvez utiliser ceci: -

extension Login_VC : UITextFieldDelegate {
    func addToolBar(textField: UITextField){
        var toolBar = UIToolbar()
        toolBar.barStyle = UIBarStyle.default
        toolBar.isTranslucent = true
        toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
        var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: "donePressed")
        var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: "cancelPressed")
        var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
        toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
        toolBar.isUserInteractionEnabled = true
        toolBar.sizeToFit()

        textField.delegate = self
        textField.inputAccessoryView = toolBar
    }
    func donePressed(){
        view.endEditing(true)
    }
    func cancelPressed(){
        view.endEditing(true) // or do something
    }
}
1
Deepak Kumar

Vous pouvez faire fonctionner une sous-classe UIToolbar en tirant parti de la chaîne de répondeurs. Pas besoin de changer vos contrôleurs de vue. Dans Swift 3:

class KeyboardAccessoryToolbar: UIToolbar {
    convenience init() {
        self.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        self.barStyle = .default
        self.isTranslucent = true
        self.tintColor = UIColor(red: 76 / 255, green: 217 / 255, blue: 100 / 255, alpha: 1)

        let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.done))
        let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancel))
        let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        self.items = [cancelButton, spaceButton, doneButton]

        self.isUserInteractionEnabled = true
        self.sizeToFit()
    }

    func done() {
        // Tell the current first responder (the current text input) to resign.
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }

    func cancel() {
        // Call "cancel" method on first object in the responder chain that implements it.
        UIApplication.shared.sendAction(#selector(cancel), to: nil, from: nil, for: nil)
    }
}

Ajoutez ensuite ce qui suit à votre applicationDidFinishLaunching pour l’appliquer à tous vos claviers:

    let accessoryView = KeyboardAccessoryToolbar()
    UITextField.appearance().inputAccessoryView = accessoryView
    UITextView.appearance().inputAccessoryView = accessoryView
0
Aaron Frary

J'ai un utilitaire que j'utilise depuis un certain temps (porté à Swift à partir d'Objective-C) qui fait ceci et un peu plus, vous pourriez le trouver utile:

https://github.com/ncerezo/SwiftKeyboardAccessory

Il crée une barre d’outils avec au moins un bouton "Terminé" pour fermer le clavier et éventuellement les boutons Suivant et Précédent. Il s’occupe également de fermer le clavier lorsque vous appuyez en dehors du champ de texte, ainsi que de redimensionner et de faire défiler la vue lorsque le clavier apparaît ou disparaît . Il est conçu pour fonctionner avec UITableVIew et également avec UIScrollView.

0
ncerezo