web-dev-qa-db-fra.com

Comment afficher le bouton "Terminé" sur le pavé numérique de l'iPhone

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?

231
Chilly Zhong

ne autre solution. Parfait s'il y a d'autres champs de texte non numériques à l'écran.

inputAccessoryView

- (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];
}
334
Luda

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()
}
49
user1258240

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.

14
davidavr

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 .

11
Michael Laszlo

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.

11
Archie

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

enter image description here

//
//  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() 
}
10
olito

Une solution beaucoup plus facile

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesBegan:touches withEvent:event];

    [textViewInstance1 resignFirstResponder];
    [textViewInstance2 resignFirstResponder];
    [textField resignFirstResponder];
}
6
iGo

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
6
Bryan

Cet article du forum explique comment personnaliser UIKeyboard pour ajouter votre vue personnalisée au clavier.

5
shek

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)
}
4
rdev5

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()
    }
}
3
Mario Hendricks

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()
}
3

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.

  1. Dans ViewController, ajoutez la méthode suivante:

    -(IBAction)closeKeyboard:(id)sender;
    
  2. Dans ViewController.m, ajoutez le code suivant:

    -(IBAction)closeKeyboard:(id)sender
    {
    
         [numberField resignFirstResponder];
    
    }
    
  3. Retournez au fichier nib.

  4. Ouvrez Utilities pan.
  5. Ouvrez le Identity inspector sous Utilities pan.
  6. Cliquez une fois sur 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.
  7. Changez la classe d'UIView en UIControl.
  8. Ouvrez Connection Inspector.
  9. Cliquez et faites glisser 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.)
  10. Sélectionnez la méthode: closeKeyboard.
  11. Exécutez le programme.

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. :-)

2
Rutvij Kotecha

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.

2
Sitric

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.

2
FluffulousChimp

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.

2
Almas Adilbek

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:

rejetant le pavé numérique

Pas besoin d'un bouton supplémentaire supplémentaire dans ce cas.

2
scipilot

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

2
horseshoe7

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()
}
1
Dx_

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.

0
John

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

0
Qiulang