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

237

Il n'y a pas de bouton "Terminé" sur le pavé numérique. Lorsqu'un utilisateur a fini de saisir des 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 basculer sur les touches numériques afin de saisir des nombres. Existe-t-il un moyen d'afficher un bouton "Terminé" sur le pavé numérique?

Chilly Zhong
la source

Réponses:

339

Une autre solution. Parfait s'il y a d'autres champs de texte non numériques sur 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];
}
Luda
la source
1
Sans doute la meilleure façon d'y parvenir. Explicitement parce qu'il adhère au HIG strict des pommes.
Hubert Kunnemeyer
3
L'autre solution est très fragile en termes de modifications graphiques apportées au clavier à l'écran.
kailoon
S'il y a plusieurs champs de texte, comment puis-je déterminer quel UITextField est en cours de modification?
Nate
Définissez votre UITextField dans le .h en tant que variable d'instance.
Luda
3
@BenPotter Vous définiriez le barTint pour la couleur de la barre et la couleur de teinte pour le texte. Vous pouvez également créer les éléments UIBarButton à l'extérieur de l'initialiseur et définir leur couleur explicitement à cet endroit.
ocross
50

Voici une adaptation de la réponse de Luda pour Swift:

Dans la déclaration de votre sous-classe UIViewController, mettez

let numberToolbar: UIToolbar = UIToolbar()

dans ViewDidLoad mis:

    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 ajouter les fonctions hoopla et hoopla (n'hésitez pas à choisir d'autres noms, changez simplement les noms des sélecteurs dans ViewDidLoad en conséquence

func boopla () {
    textField.resignFirstResponder()
}

func hoopla () {
    textField.text=""
    textField.resignFirstResponder()
}
user1258240
la source
1
UIBarButtonItemStyle.Borderedest obsolète depuis iOS 8.0. UIBarButtonItemStyle.Plainest suggéré à la place.
Jonny
Les sélecteurs doivent être mis à jour vers: #selector (YourViewController.boopla)
David V
Jonny et David ont probablement raison. Je ne programme plus pour iOS, donc je ne suis pas les changements. Si quelqu'un publie une solution mise à jour, j'y ferai référence dans une modification.
user1258240
14

L'astuce que j'ai vue consiste à créer un bouton transparent personnalisé de la taille de la vue entière, puis dans sa méthode de clic, à ce que le champ de texte démissionne en premier. L'utilisateur peut donc cliquer n'importe où en dehors du champ pour fermer le clavier.

davidavr
la source
3
Je l'ai fait en plus de la touche Retour. Cela en fait une application beaucoup plus conviviale. J'aime donner à la fois les clés de retour et les méthodes de retour en un clic.
IcyBlueRose
4
maintenant que nous avons UIGestureRecognizers, il suffit de configurer un reconnaisseur de geste de prise sur la vue principale du contrôleur de vue et de lui envoyer endEditing: YES vers sa vue. Cela fermera le clavier pour chaque champ de texte que le clavier pourrait desservir, lorsqu'il touche à l'extérieur du clavier.
chadbag
14

Une solution Swift 3 utilisant une extension. Idéal si vous avez plusieurs numériquesUITextField objets dans votre application, car cela donne la flexibilité de décider, pour chacun UITextField, d'effectuer une action personnalisée lorsque Terminé ou Annuler est appuyé.

entrez la description de l'image ici

//
//  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 à l'aide des actions par défaut:

//
// MyViewController.swift
//

@IBOutlet weak var myNumericTextField: UITextField! {
    didSet { myNumericTextField?.addDoneCancelToolbar() }
}

Exemple d'utilisation à l'aide d'une coutume action terminée :

//
// MyViewController.swift
//

@IBOutlet weak var myNumericTextField: UITextField! {
    didSet { 
        myNumericTextField?.addDoneCancelToolbar(onDone: (target: self, action: #selector(doneButtonTappedForMyNumericTextField))) 
    }
}

func doneButtonTappedForMyNumericTextField() { 
    print("Done"); 
    myNumericTextField.resignFirstResponder() 
}
oli
la source
12

Voici une refonte de la réponse de Luda avec les changements suivants:

  • la vue des accessoires est automatiquement dimensionnée à la largeur du cadre d'application

  • la constante obsolète UIBarButtonItemStyleBorderedest évitée

  • le bouton "Terminé" est instancié comme 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é pertinent.

J'ai omis un bouton "Annuler" car le clavier par défaut n'en a pas non plus. Si vous voulez un bouton "Annuler", je vous suggère de l'instancier comme un UIBarButtonSystemItemCancelet 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, peut ne pas être ce que vous voulez.

- (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 les vues personnalisées pour la saisie de données . Vous souhaiterez probablement également consulter les pages de référence sur UIToolbar et UIBarButtonItem .

Michael Laszlo
la source
[UIScreen mainScreen].applicationFrameest déconseillé dans iOS 9. Utilisation[UIScreen mainScreen].bounds
user-44651
11

La solution dans UIKeyboardTypeNumberPad et la touche de retour manquante fonctionnent très bien, mais uniquement s'il n'y a pas d'autres champs de texte non numériques sur l'écran.

J'ai pris ce code et l'ai transformé en UIViewController que vous pouvez simplement sous-classer 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.

Archie
la source
6

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
Bryan
la source
cela semble fonctionner sur le simulateur mais sur l'appareil ... je ne vois pas non plus le bouton DONE ni rien ne se passe lorsque je tape sur l'espace vide ... une idée?
xoail
14
Wow, veuillez ne pas utiliser ce code. Vous avez outrepassé les méthodes de classe à l'intérieur d'une catégorie, ce qui entraînera l'ignorance du "vrai" viewDidLoad, etc. de votre classe UIViewController.
Tony Arnold
6

Une solution beaucoup plus simple

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

    [textViewInstance1 resignFirstResponder];
    [textViewInstance2 resignFirstResponder];
    [textField resignFirstResponder];
}
Govind
la source
5

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 le générateur d'interface et vous n'aurez besoin d'aucun 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()
    }
}
Mario Hendricks
la source
Je préfère votre solution de sous-classe.
AechoLiu
5

J'ai trouvé la réponse de @ user1258240 assez concise étant donné que ce n'est pas aussi simple que de définir unreturnKeyType propriété.

Je voulais juste apporter ma propre approche "réutilisable" à ceci:

func SetDoneToolbar(field:UITextField) {
    let doneToolbar:UIToolbar = UIToolbar()

    doneToolbar.items=[
        UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil),
        UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.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)
}
Matt Borja
la source
3

SWIFT 3.0 Une saveur différente, en utilisant des parties de certaines 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()
}
Abdurrahman Mubeen Ali
la source
2

Je décris une solution pour iOS 4.2+ ici mais le bouton de apparaît en fondu 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 inclut une illusion plus élégante pour fermer le bouton, où je fane et déplace verticalement le bouton pour donner l'apparence que le clavier et le bouton sont en train de fermer ensemble.

FluffulousChimp
la source
2

La façon la plus simple est de

créer un bouton transparent personnalisé et de le placer dans le coin inférieur gauche, qui aura la même chose CGSizequ'un espace vide UIKeyboardTypeNumberPad. Basculez (affichez / masquez) ce bouton sur textField becomeFirstResponder, sur le bouton, cliquez respectivement.

Almas Adilbek
la source
2

Voici la solution la plus simple que j'ai rencontrée. J'ai appris cela du livre Beginning iOS 5 Development.

En supposant que le champ numérique est appelé 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. Revenez au nibfichier.

  4. Ouvrez la Utilitiescasserole.
  5. Ouvrez le Identity inspectordessous de la Utilitiescasserole.
  6. Cliquez une fois sur View(dans le fichier nib). Assurez-vous de n'avoir cliqué sur aucun des éléments de la vue. Par souci de clarté, vous devriez voir UIView sous ClassdansIdentity inspector .
  7. Modifiez la classe de UIView à UIControl.
  8. Ouvrez Connection Inspector.
  9. Cliquez et faites glisser Touch Downet déposez la flèche sur l' File Ownericône. (FYI ... L'icône du propriétaire du fichier s'affiche à gauche de Viewet apparaît sous la forme d'un cube creux 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 pouvoir fermer le clavier.

J'espère que cela vous aidera à résoudre votre problème. :-)

Rutvij Kotecha
la source
2

J'ai modifié la solution de Bryan pour être un peu plus robuste, afin qu'elle fonctionne bien avec d'autres types de claviers qui pourraient apparaître dans la même vue. Il est décrit ici:

Créer un bouton TERMINÉ sur le pavé numérique iOS UIKeyboard

J'essaierais de l'expliquer ici, mais la plupart est du code à regarder qui ne pourrait pas facilement tenir ici

fer à cheval7
la source
C'était la meilleure solution que j'ai trouvée pour XCode 4.5 et elle fonctionne avec iOS 6.0. Il ajoute un bouton TERMINÉ au clavier numérique. Accédez à la publication d'origine pour obtenir les graphiques du bouton TERMINÉ. neoos.ch/blog/...
Birdman
2

Si vous connaissez à l'avance le nombre de chiffres à saisir (par exemple, un code PIN à 4 chiffres), vous pouvez annuler automatiquement après 4 pressions sur les touches, conformément à ma réponse à cette question similaire:

rejet du pavé numérique

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

scipilot
la source
2

Nous pouvons également rendre la solution "utilisateur touché ailleurs" encore plus simple si nous disons simplement à la vue de notre contrôleur de vue de terminer 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 rejette le clavier" est également le comportement souhaité pour tous les autres champs modifiables de la vue.

Sitric
la source
1

Pour Swift 2.2, j'utilise ceci

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()
}
Dx_
la source
0

Toutes ces implémentations concernant la recherche de la vue du clavier et l'ajout du bouton terminé à la 3ème ligne (c'est pourquoi button.y = 163 b / c la hauteur du clavier est 216) sont fragiles car iOS continue de changer 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 trouver simplement la vue la plus haute, par [[[UIApplication sharedApplication] windows] lastObject], et d'ajouter simplement le bouton dans le coin inférieur gauche de celui-ci, doneButton.frame = CGRectMake (0, SCREEN_HEIGHT-53, 106 , 53); // mode portrait

Qiulang
la source
0

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 de table) pour ajouter le bouton Terminé à tous les claviers.

John
la source