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