Il n'y a pas de bouton "Terminé" sur le pavé numérique. Lorsqu'un utilisateur a fini d'entrer les informations numériques dans un champ de texte, comment puis-je faire disparaître le pavé numérique?
Je pourrais obtenir un bouton "Terminé" en utilisant le clavier par défaut, mais les utilisateurs devraient alors passer aux touches numériques pour pouvoir entrer des chiffres. Est-il possible d'afficher un bouton "Terminé" sur le pavé numérique?
ne autre solution. Parfait s'il y a d'autres champs de texte non numériques à l'écran.
- (void)viewDidLoad
{
[super viewDidLoad];
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
numberToolbar.barStyle = UIBarStyleBlackTranslucent;
numberToolbar.items = @[[[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelNumberPad)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:@"Apply" style:UIBarButtonItemStyleDone target:self action:@selector(doneWithNumberPad)]];
[numberToolbar sizeToFit];
numberTextField.inputAccessoryView = numberToolbar;
}
-(void)cancelNumberPad{
[numberTextField resignFirstResponder];
numberTextField.text = @"";
}
-(void)doneWithNumberPad{
NSString *numberFromTheKeyboard = numberTextField.text;
[numberTextField resignFirstResponder];
}
Voici une adaptation de la réponse de Luda à Swift:
Dans la déclaration de votre sous-classe UIViewController, mettez
let numberToolbar: UIToolbar = UIToolbar()
dans ViewDidLoad put:
numberToolbar.barStyle = UIBarStyle.BlackTranslucent
numberToolbar.items=[
UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Bordered, target: self, action: "hoopla"),
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil),
UIBarButtonItem(title: "Apply", style: UIBarButtonItemStyle.Bordered, target: self, action: "boopla")
]
numberToolbar.sizeToFit()
textField.inputAccessoryView = numberToolbar //do it for every relevant textfield if there are more than one
et ajoutez les fonctions hoopla et hoopla (n'hésitez pas à choisir d'autres noms, il suffit de modifier les noms des sélecteurs dans ViewDidLoad en conséquence
func boopla () {
textField.resignFirstResponder()
}
func hoopla () {
textField.text=""
textField.resignFirstResponder()
}
Le truc que j'ai vu utilisé est de créer un bouton transparent personnalisé de la taille de la vue entière, puis, dans sa méthode de clic, de faire en sorte que le champ de texte annule la réponse en premier. Ainsi, l'utilisateur peut cliquer n'importe où en dehors du champ pour fermer le clavier.
Vous trouverez ci-dessous une révision de la réponse de Luda avec les modifications suivantes:
la vue accessoire est automatiquement dimensionnée à la largeur du cadre d'application
la constante obsolète UIBarButtonItemStyleBordered
est évitée
le bouton "Terminé" est instancié en tant que UIBarButtonSystemItemDone
Actuellement, le bouton "Terminé" est centré dans la vue des accessoires. Vous pouvez le positionner à gauche ou à droite en supprimant l’espace du côté concerné.
J'ai omis un bouton "Annuler" car le clavier par défaut n'en a pas non plus. Si vous souhaitez un bouton "Annuler", je vous suggère de l'instancier en tant que UIBarButtonSystemItemCancel
et de vous assurer que vous ne supprimez pas la valeur d'origine dans votre champ de texte. Le comportement "Annuler" implémenté dans la réponse de Luda, qui écrase la valeur avec une chaîne vide, n'est peut-être pas ce que vous souhaitez.
- (void)viewDidLoad {
[super viewDidLoad];
float appWidth = CGRectGetWidth([UIScreen mainScreen].applicationFrame);
UIToolbar *accessoryView = [[UIToolbar alloc]
initWithFrame:CGRectMake(0, 0, appWidth, 0.1 * appWidth)];
UIBarButtonItem *space = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
UIBarButtonItem *done = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(selectDoneButton)];
accessoryView.items = @[space, done, space];
self.valueField.inputAccessoryView = accessoryView;
}
- (void)selectDoneButton {
[self.valueField resignFirstResponder];
}
Pour plus d'informations sur la création de vues d'accessoires, consultez la documentation Apple sur vues personnalisées pour la saisie de données . Vous voudrez probablement consulter les pages de référence sur IToolbar et IBarButtonItem .
La solution dans IKeyboardTypeNumberPad et clé de retour manquante fonctionne très bien, mais uniquement s’il n’y a pas d’autres champs de texte de pavé numérique à l’écran.
J'ai pris ce code et l'ai transformé en un UIViewController que vous pouvez simplement sous-classe pour faire fonctionner les pavés numériques. Vous devrez obtenir les icônes à partir du lien ci-dessus.
NumberPadViewController.h:
#import <UIKit/UIKit.h>
@interface NumberPadViewController : UIViewController {
UIImage *numberPadDoneImageNormal;
UIImage *numberPadDoneImageHighlighted;
UIButton *numberPadDoneButton;
}
@property (nonatomic, retain) UIImage *numberPadDoneImageNormal;
@property (nonatomic, retain) UIImage *numberPadDoneImageHighlighted;
@property (nonatomic, retain) UIButton *numberPadDoneButton;
- (IBAction)numberPadDoneButton:(id)sender;
@end
et NumberPadViewController.m:
#import "NumberPadViewController.h"
@implementation NumberPadViewController
@synthesize numberPadDoneImageNormal;
@synthesize numberPadDoneImageHighlighted;
@synthesize numberPadDoneButton;
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
if ([super initWithNibName:nibName bundle:nibBundle] == nil)
return nil;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0) {
self.numberPadDoneImageNormal = [UIImage imageNamed:@"DoneUp3.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"DoneDown3.png"];
} else {
self.numberPadDoneImageNormal = [UIImage imageNamed:@"DoneUp.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"DoneDown.png"];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Add listener for keyboard display events
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
// Add listener for all text fields starting to be edited
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textFieldDidBeginEditing:)
name:UITextFieldTextDidBeginEditingNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextFieldTextDidBeginEditingNotification
object:nil];
[super viewWillDisappear:animated];
}
- (UIView *)findFirstResponderUnder:(UIView *)root {
if (root.isFirstResponder)
return root;
for (UIView *subView in root.subviews) {
UIView *firstResponder = [self findFirstResponderUnder:subView];
if (firstResponder != nil)
return firstResponder;
}
return nil;
}
- (UITextField *)findFirstResponderTextField {
UIResponder *firstResponder = [self findFirstResponderUnder:[self.view window]];
if (![firstResponder isKindOfClass:[UITextField class]])
return nil;
return (UITextField *)firstResponder;
}
- (void)updateKeyboardButtonFor:(UITextField *)textField {
// Remove any previous button
[self.numberPadDoneButton removeFromSuperview];
self.numberPadDoneButton = nil;
// Does the text field use a number pad?
if (textField.keyboardType != UIKeyboardTypeNumberPad)
return;
// If there's no keyboard yet, don't do anything
if ([[[UIApplication sharedApplication] windows] count] < 2)
return;
UIWindow *keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
// Create new custom button
self.numberPadDoneButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.numberPadDoneButton.frame = CGRectMake(0, 163, 106, 53);
self.numberPadDoneButton.adjustsImageWhenHighlighted = FALSE;
[self.numberPadDoneButton setImage:self.numberPadDoneImageNormal forState:UIControlStateNormal];
[self.numberPadDoneButton setImage:self.numberPadDoneImageHighlighted forState:UIControlStateHighlighted];
[self.numberPadDoneButton addTarget:self action:@selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
// Locate keyboard view and add button
NSString *keyboardPrefix = [[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2 ? @"<UIPeripheralHost" : @"<UIKeyboard";
for (UIView *subView in keyboardWindow.subviews) {
if ([[subView description] hasPrefix:keyboardPrefix]) {
[subView addSubview:self.numberPadDoneButton];
[self.numberPadDoneButton addTarget:self action:@selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
break;
}
}
}
- (void)textFieldDidBeginEditing:(NSNotification *)note {
[self updateKeyboardButtonFor:[note object]];
}
- (void)keyboardWillShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
- (void)keyboardDidShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
- (IBAction)numberPadDoneButton:(id)sender {
UITextField *textField = [self findFirstResponderTextField];
[textField resignFirstResponder];
}
- (void)dealloc {
[numberPadDoneImageNormal release];
[numberPadDoneImageHighlighted release];
[numberPadDoneButton release];
[super dealloc];
}
@end
Prendre plaisir.
Une solution Swift 3 utilisant une extension. Idéal si vous avez plusieurs objets UITextField
numériques dans votre application, car cela vous donne la possibilité de décider, pour chaque UITextField
, si vous souhaitez exécuter une action personnalisée lorsque Fait ou Annuler est sélectionné.
//
// UITextField+DoneCancelToolbar.Swift
//
import UIKit
extension UITextField {
func addDoneCancelToolbar(onDone: (target: Any, action: Selector)? = nil, onCancel: (target: Any, action: Selector)? = nil) {
let onCancel = onCancel ?? (target: self, action: #selector(cancelButtonTapped))
let onDone = onDone ?? (target: self, action: #selector(doneButtonTapped))
let toolbar: UIToolbar = UIToolbar()
toolbar.barStyle = .default
toolbar.items = [
UIBarButtonItem(title: "Cancel", style: .plain, target: onCancel.target, action: onCancel.action),
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
UIBarButtonItem(title: "Done", style: .done, target: onDone.target, action: onDone.action)
]
toolbar.sizeToFit()
self.inputAccessoryView = toolbar
}
// Default actions:
func doneButtonTapped() { self.resignFirstResponder() }
func cancelButtonTapped() { self.resignFirstResponder() }
}
Exemple d'utilisation utilisant les actions par défaut:
//
// MyViewController.Swift
//
@IBOutlet weak var myNumericTextField: UITextField! {
didSet { myNumericTextField?.addDoneCancelToolbar() }
}
Exemple d'utilisation utilisant une action personnalisée effectuée :
//
// MyViewController.Swift
//
@IBOutlet weak var myNumericTextField: UITextField! {
didSet {
myNumericTextField?.addDoneCancelToolbar(onDone: (target: self, action: #selector(doneButtonTappedForMyNumericTextField)))
}
}
func doneButtonTappedForMyNumericTextField() {
print("Done");
myNumericTextField.resignFirstResponder()
}
Une solution beaucoup plus facile
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[textViewInstance1 resignFirstResponder];
[textViewInstance2 resignFirstResponder];
[textField resignFirstResponder];
}
Voici le code le plus récent. Incluez simplement #import "UIViewController + NumPadReturn.h" dans votre viewController.
Voici le .h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface UIViewController (NumPadReturn)
@end
Et eux
#import "UIViewController+NumPadReturn.h"
@implementation UIViewController (NumPadReturn)
-(void) viewDidLoad{
// add observer for the respective notifications (depending on the os version)
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
}
- (void)keyboardWillShow:(NSNotification *)note {
// if clause is just an additional precaution, you could also dismiss it
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 3.2) {
[self addButtonToKeyboard];
}
}
- (void)keyboardDidShow:(NSNotification *)note {
// if clause is just an additional precaution, you could also dismiss it
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[self addButtonToKeyboard];
}
}
- (void)addButtonToKeyboard {
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0) {
[doneButton setImage:[UIImage imageNamed:@"DoneUp3.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown3.png"] forState:UIControlStateHighlighted];
} else {
[doneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
}
[doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
[keyboard addSubview:doneButton];
} else {
if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
[keyboard addSubview:doneButton];
}
}
}
- (void)doneButton:(id)sender {
NSLog(@"doneButton");
[self.view endEditing:TRUE];
}
@end
Cet article du forum explique comment personnaliser UIKeyboard pour ajouter votre vue personnalisée au clavier.
J'ai trouvé que la réponse de @ user125824 est plutôt concis, car ce n'est pas aussi simple que de définir une propriété returnKeyType
.
Je voulais juste apporter ma propre approche "réutilisable" à ceci:
func SetDoneToolbar(field:UITextField) {
let doneToolbar:UIToolbar = UIToolbar()
doneToolbar.items=[
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: self, action: nil),
UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.dismissKeyboard))
]
doneToolbar.sizeToFit()
field.inputAccessoryView = doneToolbar
}
override func viewDidLoad() {
super.viewDidLoad()
SetDoneToolbar(field: UITextField_1)
SetDoneToolbar(field: UITextField_2)
SetDoneToolbar(field: UITextField_3)
SetDoneToolbar(field: UITextField_N)
}
Si vous avez plusieurs champs numériques, je suggère de sous-classer UITextField pour créer un NumericTextField qui affiche toujours un clavier numérique avec un bouton Terminé. Ensuite, associez simplement vos champs numériques à cette classe dans Interface Builder pour ne plus avoir besoin de code supplémentaire dans aucun de vos contrôleurs de vue. Ce qui suit est la classe Swift 3.0 que j'utilise dans Xcode 8.0.
class NumericTextField: UITextField {
let numericKbdToolbar = UIToolbar()
// MARK: Initilization
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialize()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.initialize()
}
// Sets up the input accessory view with a Done button that closes the keyboard
func initialize()
{
self.keyboardType = UIKeyboardType.numberPad
numericKbdToolbar.barStyle = UIBarStyle.default
let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let callback = #selector(NumericTextField.finishedEditing)
let donebutton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: callback)
numericKbdToolbar.setItems([space, donebutton], animated: false)
numericKbdToolbar.sizeToFit()
self.inputAccessoryView = numericKbdToolbar
}
// MARK: On Finished Editing Function
func finishedEditing()
{
self.resignFirstResponder()
}
}
Swift 4.2
class NumericTextField: UITextField {
let numericKbdToolbar = UIToolbar()
// MARK: Initilization
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialize()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.initialize()
}
// Sets up the input accessory view with a Done button that closes the keyboard
func initialize()
{
self.keyboardType = UIKeyboardType.numberPad
numericKbdToolbar.barStyle = UIBarStyle.default
let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let callback = #selector(NumericTextField.finishedEditing)
let donebutton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: callback)
numericKbdToolbar.setItems([space, donebutton], animated: false)
numericKbdToolbar.sizeToFit()
self.inputAccessoryView = numericKbdToolbar
}
// MARK: On Finished Editing Function
@objc func finishedEditing()
{
self.resignFirstResponder()
}
}
Swift 3. Une autre saveur, en utilisant des parties de réponses précédentes.
func addToolbarToNumberPad()
{
let numberPadToolbar: UIToolbar = UIToolbar()
numberPadToolbar.isTranslucent = true
numberPadToolbar.items=[
UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancelAction)),
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
UIBarButtonItem(title: "Custom", style: .done, target: self, action: #selector(self.customAction)),
UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.doneAction)),
]
numberPadToolbar.sizeToFit()
textField.inputAccessoryView = numberPadToolbar
}
func cancelAction()
{
textField.resignFirstResponder()
}
func customAction()
{
textField.resignFirstResponder()
}
func doneAction()
{
textField.resignFirstResponder()
}
override func viewDidLoad()
{
super.viewDidLoad()
self.addToolbarToNumberPad()
}
Voici la solution la plus simple que j'ai rencontrée. Je l'ai appris dans le livre de démarrage du développement iOS 5.
En supposant que le champ numérique s'appelle numberField
.
Dans ViewController
, ajoutez la méthode suivante:
-(IBAction)closeKeyboard:(id)sender;
Dans ViewController.m
, ajoutez le code suivant:
-(IBAction)closeKeyboard:(id)sender
{
[numberField resignFirstResponder];
}
Retournez au fichier nib
.
Utilities
pan.Identity inspector
sous Utilities
pan.View
(dans le fichier nib). Assurez-vous que vous n'avez cliqué sur aucun des éléments de la vue. Par souci de clarté, vous devriez voir UIView sous Class
dans Identity inspector
.Connection Inspector
.Touch Down
et déposez la flèche sur l'icône File Owner
. (L'icône ... Propriétaire du fichier est affichée à gauche de View
et apparaît sous la forme d'un cube vide avec un cadre jaune.)closeKeyboard
.Maintenant, lorsque vous cliquez n'importe où sur l'arrière-plan de View
, vous devriez être en mesure de fermer le clavier.
J'espère que cela vous aide à résoudre votre problème. :-)
Nous pouvons également rendre la solution "l'utilisateur touché ailleurs" encore plus simple si nous indiquons simplement à notre contrôleur de vue de mettre fin à l'édition. :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[self.view endEditing:YES]; //YES ignores any textfield refusal to resign
}
... en supposant que "toucher ailleurs ferme le clavier" est le comportement souhaité pour tous les autres champs modifiables de la vue.
Je décris une solution pour iOS 4.2+ ici mais le bouton de suppression s’efface après l’apparition du clavier. Ce n'est pas terrible, mais pas idéal non plus.
La solution décrite dans la question liée ci-dessus comprend une illusion plus élégante consistant à ignorer le bouton. Je fondais et déplaçais verticalement le bouton pour fournir l’apparence que le clavier et le bouton font disparaître ensemble.
Le le plus simple moyen est:
Créez bouton transparent personnalisé et placez-le dans le coin inférieur gauche, qui aura le même CGSize
qu'un espace vide dans UIKeyboardTypeNumberPad
. Activez (affichez/masquez) ce bouton sur textField becomeFirstResponder
, sur le clic du bouton.
Si vous connaissez à l'avance le nombre de numéros à saisir (par exemple un code PIN à 4 chiffres), vous pouvez vous en prémunir automatiquement après 4 pressions de touche, conformément à ma réponse à cette question similaire:
Pas besoin d'un bouton supplémentaire supplémentaire dans ce cas.
J'ai modifié la solution de Bryan pour qu'elle soit un peu plus robuste, de sorte qu'elle fonctionne bien avec d'autres types de claviers susceptibles d'apparaître dans la même vue. C'est décrit ici:
Créer un bouton DONE sur le pavé numérique iOS UIKeyboard
J'essaierais de l'expliquer ici, mais l'essentiel est du code à regarder qui ne conviendrait pas facilement ici
Pour Swift 2.2, je l’utilise
func addDoneButtonOnKeyboard() {
let doneToolbar: UIToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.bounds.size.width, 50))
let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: #selector(DetailViewController.finishDecimalKeypad))
var items: [UIBarButtonItem]? = [UIBarButtonItem]()
items?.append(flexSpace)
items?.append(done)
doneToolbar.items = items
doneToolbar.sizeToFit()
self.productPrice.inputAccessoryView=doneToolbar
}
func finishDecimalKeypad() {
self.productPrice?.resignFirstResponder()
}
Swift 2.2/J'ai utilisé la réponse de Dx_. Cependant, je voulais cette fonctionnalité sur tous les claviers. Donc, dans ma classe de base, j'ai mis le code:
func addDoneButtonForTextFields(views: [UIView]) {
for view in views {
if let textField = view as? UITextField {
let doneToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.bounds.size.width, 50))
let flexSpace = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
let done = UIBarButtonItem(title: "Done", style: .Done, target: self, action: #selector(dismissKeyboard))
var items = [UIBarButtonItem]()
items.append(flexSpace)
items.append(done)
doneToolbar.items = items
doneToolbar.sizeToFit()
textField.inputAccessoryView = doneToolbar
} else {
addDoneButtonForTextFields(view.subviews)
}
}
}
func dismissKeyboard() {
dismissKeyboardForTextFields(self.view.subviews)
}
func dismissKeyboardForTextFields(views: [UIView]) {
for view in views {
if let textField = view as? UITextField {
textField.resignFirstResponder()
} else {
dismissKeyboardForTextFields(view.subviews)
}
}
}
Ensuite, appelez simplement addDoneButtonForTextFields sur self.view.subviews dans viewDidLoad (ou willDisplayCell si vous utilisez une vue sous forme de tableau) pour ajouter le bouton Terminé à tous les claviers.
Toutes les implémentations relatives à la recherche de la vue clavier et à l'ajout du bouton done à la 3ème ligne (raison pour laquelle button.y = 163 hauteur du clavier b/c est 216) sont fragiles, car iOS continue de modifier la hiérarchie des vues. Par exemple, aucun des codes ci-dessus ne fonctionne pour iOS9.
Je pense qu'il est plus sûr de simplement trouver la vue la plus haute, par [[[[UIApplication sharedApplication] windows] lastObject], et d'ajouter simplement le bouton dans le coin inférieur gauche, doneButton.frame = CGRectMake (0, SCREEN_HEIGHT-53, 106 , 53); // mode portrait