Cómo mostrar el botón "Listo" en el teclado numérico del iPhone

237

No hay un botón "Listo" en el teclado numérico. Cuando un usuario termina de ingresar información numérica en un campo de texto, ¿cómo puedo hacer que desaparezca el teclado numérico?

Podría obtener un botón "Listo" utilizando el teclado predeterminado, pero luego los usuarios tendrían que cambiar a las teclas numéricas para ingresar números. ¿Hay alguna manera de mostrar un botón "Listo" en el teclado numérico?

Zhong frío
fuente

Respuestas:

339

Otra solución. Perfecto si hay otros campos de texto de teclado no numérico en la pantalla.

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
fuente
1
Sin duda, la mejor manera de lograr esto. Explícitamente porque se adhiere a las manzanas estrictas HIG.
Hubert Kunnemeyer
3
La otra solución es muy frágil en términos de que cualquier cambio gráfico en el teclado en pantalla lo romperá.
kailoon
Si hay varios campos de texto, ¿cómo determino qué UITextField se está editando?
Nate
Defina su UITextField en el .h como una variable de instancia.
Luda
3
@BenPotter Establecería el color de barra para el color de barra y el color de tinta para el texto. También puede crear los elementos UIBarButton fuera del intializador y establecer el color para ellos explícitamente allí.
través
50

Aquí hay una adaptación para la respuesta de Luda para Swift:

En la declaración de su subclase UIViewController ponga

let numberToolbar: UIToolbar = UIToolbar()

en ViewDidLoad poner:

    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 

y agregue las funciones hoopla y hoopla (siéntase libre de elegir otros nombres, simplemente cambie los nombres del selector en ViewDidLoad en consecuencia

func boopla () {
    textField.resignFirstResponder()
}

func hoopla () {
    textField.text=""
    textField.resignFirstResponder()
}
usuario1258240
fuente
1
UIBarButtonItemStyle.Borderedestá en desuso desde iOS 8.0. UIBarButtonItemStyle.Plainse sugiere en su lugar.
Jonny
Los selectores deben actualizarse a: #selector (YourViewController.boopla)
David V
Jonny y David probablemente tengan razón. Ya no estoy programando para iOS, así que no sigo los cambios. Si alguien publica una solución actualizada, me referiré a ella en una edición.
user1258240
14

El truco que he visto es crear un botón transparente personalizado del tamaño de la vista completa y luego, en su método de clic, hacer que el campo de texto renuncie al primer respondedor. Por lo tanto, el usuario puede hacer clic en cualquier lugar fuera del campo para descartar el teclado.

davidavr
fuente
3
He hecho esto además de la tecla Retorno. Es una aplicación mucho más fácil de usar. Me gusta dar las teclas de retorno y los métodos de retorno de clic en cualquier lugar.
IcyBlueRose
44
ahora que tenemos UIGestureRecognizers, simplemente configure un reconocedor de gestos de toque en la vista del controlador de vista principal y haga que envíe endEditing: YES a su vista. Esto cerrará el teclado para cada campo de texto que el teclado podría estar atendiendo, al tocar fuera del teclado.
chadbag
14

Una solución Swift 3 usando una extensión. Ideal si tiene varios UITextFieldobjetos numéricos en su aplicación, ya que le da la flexibilidad para decidir, para cada uno UITextField, si desea realizar una acción personalizada cuando se toca Listo o Cancelar .

ingrese la descripción de la imagen aquí

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

Ejemplo de uso con las acciones predeterminadas:

//
// MyViewController.swift
//

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

Ejemplo de uso con una acción Listo personalizada :

//
// MyViewController.swift
//

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

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

A continuación se muestra una revisión de la respuesta de Luda con los siguientes cambios:

  • la vista de accesorios se ajusta automáticamente al ancho del marco de la aplicación

  • UIBarButtonItemStyleBorderedse evita la constante obsoleta

  • el botón "Listo" se instancia como UIBarButtonSystemItemDone

Actualmente, el botón "Listo" está centrado en la vista de accesorios. Puede colocarlo a la izquierda o derecha eliminando el espacio en el lado pertinente.

He omitido un botón "Cancelar" porque el teclado predeterminado tampoco tiene uno. Si desea un botón "Cancelar", le sugiero que lo cree una instancia UIBarButtonSystemItemCancely que se asegure de no descartar el valor original en su campo de texto. El comportamiento "Cancelar" implementado en la respuesta de Luda, que sobrescribe el valor con una cadena en blanco, puede no ser lo que desea.

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

Para obtener más información sobre cómo crear vistas de accesorios, consulte la documentación de Apple sobre vistas personalizadas para la entrada de datos . Probablemente también desee consultar las páginas de referencia en UIToolbar y UIBarButtonItem .

Michael Laszlo
fuente
[UIScreen mainScreen].applicationFrameestá en desuso en iOS 9. Uso[UIScreen mainScreen].bounds
usuario-44651
11

La solución en UIKeyboardTypeNumberPad y la tecla de retorno faltante funciona muy bien, pero solo si no hay otros campos de texto que no sean números en la pantalla.

Tomé ese código y lo convertí en un UIViewController que simplemente puede subclasificar para que funcionen los botones numéricos. Deberá obtener los iconos del enlace anterior.

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

y 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

Disfrutar.

Archie
fuente
6

Aquí está el código más reciente. Simplemente incluya #import "UIViewController + NumPadReturn.h" en su viewController.

Aquí está el .h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface UIViewController (NumPadReturn)



@end

Y ellos

#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
fuente
esto parece funcionar en el simulador pero en el dispositivo ... ni puedo ver el botón HECHO ni sucede nada cuando toco el espacio vacío ... ¿alguna idea?
xoail
14
Wow, por favor no uses este código. Reemplaza los métodos de clase dentro de una categoría, lo que hará que se ignore el "real" viewDidLoad, etc. de su clase UIViewController.
Tony Arnold el
6

Una solución mucho más fácil

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

    [textViewInstance1 resignFirstResponder];
    [textViewInstance2 resignFirstResponder];
    [textField resignFirstResponder];
}
Govind
fuente
5

Si tiene varios campos numéricos, sugiero subclasificar UITextField para crear un NumericTextField que siempre muestre un teclado numérico con un botón listo. Luego, simplemente asocie sus campos numéricos con esta clase en el Creador de interfaces y no necesitará ningún código adicional en ninguno de sus Controladores de vista. La siguiente es la clase Swift 3.0 que estoy usando en 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
fuente
Prefiero su solución de subclase.
AechoLiu
5

He encontrado @ respuesta de user1258240 que debe darse bastante concisa esto no es tan simple como el establecimiento de una returnKeyTypepropiedad.

Solo quería contribuir con mi propio enfoque "reutilizable" para esto:

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
fuente
3

SWIFT 3.0 Un sabor diferente, utilizando partes de algunas respuestas anteriores.

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
fuente
2

Describo una solución para iOS 4.2+ aquí, pero el botón de descarte desaparece después de que aparece el teclado. No es terrible, pero tampoco es ideal.

La solución descrita en la pregunta vinculada anteriormente incluye una ilusión más elegante para descartar el botón, donde me desvanezco y desplazo verticalmente el botón para proporcionar la apariencia de que el teclado y el botón se descartan juntos.

FluffulousChimp
fuente
2

La forma más sencilla es:

crear un botón transparente personalizado y colocarlo en la esquina inferior izquierda, que tendrá el mismo CGSizeespacio vacío UIKeyboardTypeNumberPad. Alternar (mostrar / ocultar) este botón en textField becomeFirstResponder, al hacer clic en el botón respectivamente.

Almas Adilbek
fuente
2

Aquí está la solución más simple que he encontrado. He aprendido esto del libro Principio de desarrollo de iOS 5.

Suponiendo que se llame al campo de número numberField.

  1. En ViewController, agregue el siguiente método:

    -(IBAction)closeKeyboard:(id)sender;
  2. En ViewController.m, agregue el siguiente código:

    -(IBAction)closeKeyboard:(id)sender
    {
    
         [numberField resignFirstResponder];
    
    }
  3. Regrese al nibarchivo.

  4. UtilitiesPan abierto
  5. Abra la sartén Identity inspectordebajo Utilities.
  6. Haga clic en View(en el archivo plumín) una vez. Asegúrese de no haber hecho clic en ninguno de los elementos de la vista. En aras de la aclaración, debería ver UIView debajo Classen Identity inspector.
  7. Cambia la clase de UIView a UIControl.
  8. Abierto Connection Inspector.
  9. Haga clic y arrastre Touch Downy suelte la flecha en el File Ownericono. (FYI ... El icono del propietario del archivo se muestra a la izquierda de Viewy aparece como un cubo hueco con marco amarillo).
  10. Seleccionar el método: closeKeyboard.
  11. Ejecuta el programa.

Ahora, cuando hace clic en cualquier parte del fondo View, debería poder cerrar el teclado.

Espero que esto te ayude a resolver tu problema. :-)

Rutvij Kotecha
fuente
2

Modifiqué la solución de Bryan para que fuera un poco más robusta, de modo que funcionara bien con otros tipos de teclados que podrían aparecer en la misma vista. Se describe aquí:

Cree un botón HECHO en el teclado numérico UIKeyboard de iOS

Trataría de explicarlo aquí, pero la mayor parte es un código para mirar que no encajaría fácilmente aquí

herradura7
fuente
Esta fue la mejor solución que encontré para XCode 4.5 y funciona con iOS 6.0. Agrega un botón HECHO al teclado numérico. Vaya a la publicación original para obtener los gráficos del botón HECHO. neoos.ch/blog/...
hombre pájaro
2

Si sabe de antemano la cantidad de números que se ingresarán (por ejemplo, un PIN de 4 dígitos), puede descartar automáticamente después de presionar 4 teclas, según mi respuesta a esta pregunta similar:

descartar el teclado numérico

No es necesario un botón de finalización adicional en este caso.

scipilot
fuente
2

También podemos simplificar aún más la solución de "usuario tocado en otro lugar" si solo le decimos a nuestro controlador de vista que finalice la edición:

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

      [self.view endEditing:YES]; //YES ignores any textfield refusal to resign
 }

... suponiendo que "tocar otro lugar descarta el teclado" es el comportamiento deseado para cualquier otro campo editable en la vista también.

Sitric
fuente
1

Para Swift 2.2 yo uso esto

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_
fuente
0

Todas esas implementaciones sobre cómo encontrar la vista del teclado y agregar el botón listo en la tercera fila (es por eso que button.y = 163 b / c la altura del teclado es 216) son frágiles porque iOS cambia la jerarquía de la vista. Por ejemplo, ninguno de los códigos anteriores funciona para iOS9.

Creo que es más seguro encontrar la vista superior, por [[[UIApplication sharedApplication] windows] lastObject], y simplemente agregar el botón en la esquina inferior izquierda, doneButton.frame = CGRectMake (0, SCREEN_HEIGHT-53, 106 , 53); // modo retrato

Qiulang
fuente
0

Swift 2.2 / Usé la respuesta de Dx_. Sin embargo, quería esta funcionalidad en todos los teclados. Entonces en mi clase base pongo el código:

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

Luego simplemente llame a addDoneButtonForTextFields en self.view.subviews en viewDidLoad (o willDisplayCell si usa una vista de tabla) para agregar el botón Listo a todos los teclados.

Juan
fuente