Como mostrar o botão "Concluído" no teclado numérico do iPhone


237

Não há botão "Concluído" no teclado numérico. Quando um usuário termina de inserir informações numéricas em um campo de texto, como faço para que o teclado numérico desapareça?

Eu poderia obter um botão "Concluído" usando o teclado padrão, mas os usuários teriam que mudar para as teclas numéricas para inserir números. Existe uma maneira de mostrar um botão "Concluído" no teclado numérico?

Respostas:


339

Outra solução. Perfeito se houver outros campos de texto sem teclado numérico na tela.

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

1
Sem dúvida, a melhor maneira de conseguir isso. Explicitamente porque adere às maçãs estritas HIG.
Hubert Kunnemeyer

3
A outra solução é muito quebradiça em termos de alterações gráficas no teclado na tela.
kailoon

Se houver vários campos de texto, como determino qual UITextField está sendo editado?
Nate

Defina seu UITextField no .h como uma variável de instância.
Luda

3
@BenPotter Você definiria o barTint para a cor da barra e a cor do texto. Você também pode criar os itens UIBarButton fora do intializer e definir explicitamente a cor para eles.
Ocross

50

Aqui está uma adaptação para a resposta de Luda para Swift:

Na declaração da sua subclasse UIViewController, coloque

let numberToolbar: UIToolbar = UIToolbar()

em ViewDidLoad colocar:

    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 

e adicione as funções hoopla e hoopla (fique à vontade para escolher outros nomes, basta alterar os nomes do seletor no ViewDidLoad de acordo

func boopla () {
    textField.resignFirstResponder()
}

func hoopla () {
    textField.text=""
    textField.resignFirstResponder()
}

1
UIBarButtonItemStyle.Borderedestá obsoleto desde o iOS 8.0. UIBarButtonItemStyle.Plainé sugerido em seu lugar.
9139 Jonny

Os seletores devem ser atualizados para: #selector (YourViewController.boopla)
David V

Jonny e David provavelmente estão certos. Não estou mais programando para iOS, portanto não sigo as alterações. Se alguém postar uma solução atualizada, eu me referirei a ela em uma edição.
User1258240

14

O truque que eu vi usado é criar um botão transparente personalizado do tamanho de toda a exibição e, em seu método de clique, fazer com que o campo de texto renuncie primeiro. Assim, o usuário pode clicar em qualquer lugar fora do campo para descartar o teclado.


3
Eu fiz isso além da tecla Return. Torna um aplicativo muito mais fácil de usar. Gosto de fornecer as chaves de retorno e o clique em qualquer lugar.
IcyBlueRose

4
agora que temos o UIGestureRecognizers, basta configurar um reconhecedor de gestos de toque na visualização principal do controlador de exibição e mandar enviar endEditing: YES para a visualização. Isso fechará o teclado para todos os campos de texto que o teclado possa atender, ao tocar fora do teclado.
chadbag

14

Uma solução Swift 3 usando uma extensão. Ideal se você tiver vários UITextFieldobjetos numéricos no seu aplicativo, pois oferece a flexibilidade de decidir, para cada um UITextField, se uma ação personalizada deve ser executada quando Done ou Cancel for pressionado.

insira a descrição da imagem aqui

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

Exemplo de uso usando as ações padrão:

//
// MyViewController.swift
//

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

Exemplo de uso usando uma ação Concluída personalizada :

//
// MyViewController.swift
//

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

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

12

Abaixo está uma revisão da resposta de Luda com as seguintes alterações:

  • a vista acessória é dimensionada automaticamente para a largura do quadro do aplicativo

  • a constante obsoleta UIBarButtonItemStyleBorderedé evitada

  • o botão "Concluído" é instanciado como UIBarButtonSystemItemDone

Atualmente, o botão "Concluído" está centralizado na visualização de acessórios. Você pode posicioná-lo à esquerda ou à direita excluindo o espaço no lado pertinente.

Omiti o botão "Cancelar" porque o teclado padrão também não possui um. Se você deseja um botão "Cancelar", sugiro que você o instale como um UIBarButtonSystemItemCancele verifique se não está descartando o valor original no seu campo de texto. O comportamento "Cancelar" implementado na resposta de Luda, que substitui o valor por uma sequência em branco, pode não ser o que você deseja.

- (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 obter mais informações sobre como criar visualizações de acessórios, consulte a documentação da Apple sobre visualizações personalizadas para entrada de dados . Você provavelmente também desejará consultar as páginas de referência em UIToolbar e UIBarButtonItem .


[UIScreen mainScreen].applicationFramefoi descontinuado no iOS 9. Use[UIScreen mainScreen].bounds
user-44651 21/02

11

A solução em UIKeyboardTypeNumberPad e a tecla de retorno ausente funciona muito bem, mas apenas se não houver outros campos de texto que não sejam o número numérico na tela.

Peguei esse código e o transformei em um UIViewController, no qual você pode simplesmente subclasse para fazer o teclado numérico funcionar. Você precisará obter os ícones no link acima.

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

e 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

Aproveitar.


6

Aqui está o código mais recente. Simplesmente inclua #import "UIViewController + NumPadReturn.h" no seu viewController.

Aqui está o .h

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

@interface UIViewController (NumPadReturn)



@end

E eles

#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

isso parece funcionar no simulador, mas no dispositivo ... nem consigo ver o botão CONCLUÍDO, nem acontece alguma coisa quando toco no espaço vazio ... alguma ideia?
xoail 23/05

14
Uau, por favor, não use este código. Você substituiu os métodos de classe de dentro de uma categoria, o que fará com que o viewDidLoad "real" etc da sua classe UIViewController seja ignorado.
Tony Arnold

6

Uma solução muito mais fácil

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

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

5

Se você tiver vários campos numéricos, sugiro subclassificar UITextField para criar um NumericTextField que sempre exibe um teclado numérico com um botão concluído. Em seguida, basta associar seus campos numéricos a essa classe no Interface Builder e você não precisará de nenhum código adicional em nenhum dos seus View Controllers. A seguir, a classe Swift 3.0 que estou usando no 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()
    }
}

Eu prefiro sua solução de subclasse.
AechoLiu

5

Achei a resposta do @ user1258240 bastante concisa, pois isso não é tão simples quanto definir umreturnKeyType propriedade.

Só queria contribuir com minha própria abordagem "reutilizável" para isso:

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

3

SWIFT 3.0 Um sabor diferente, usando partes de algumas respostas 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()
}

2

Descrevo uma solução para iOS 4.2 ou superior aqui mas o botão de descartar desaparece após o teclado aparecer. Não é terrível, mas também não é o ideal.

A solução descrita na pergunta vinculada acima inclui uma ilusão mais elegante de descartar o botão, onde desboto e desloco verticalmente o botão para fornecer a aparência de que o teclado e o botão estão descartando juntos.


2

A maneira mais simples é:

Criar botão transparente personalizado e coloque-o no canto inferior esquerdo, que terá o mesmo CGSizeespaço vazio UIKeyboardTypeNumberPad. Alterne (mostrar / ocultar) este botão no campo de texto becomeFirstResponder, clique no botão, respectivamente.


2

Aqui está a solução mais simples que encontrei. Aprendi isso com o livro Beginning iOS 5 Development.

Supondo que o campo numérico seja chamado numberField.

  1. Em ViewController, adicione o seguinte método:

    -(IBAction)closeKeyboard:(id)sender;
  2. Em ViewController.m, adicione o seguinte código:

    -(IBAction)closeKeyboard:(id)sender
    {
    
         [numberField resignFirstResponder];
    
    }
  3. Volte ao nibarquivo.

  4. Abrir UtilitiesPanela .
  5. Abra a parte Identity inspectorinferiorUtilities panela de .
  6. Clique no View(no arquivo da ponta) uma vez. Verifique se você não clicou em nenhum dos itens da exibição. Para fins de esclarecimento, você deve ver o UIView ClassemIdentity inspector .
  7. Mude a classe de UIView para UIControl.
  8. Aberto Connection Inspector.
  9. Clique e arraste Touch Downe solte a seta no File Ownerícone. (FYI ... O ícone Proprietário do arquivo é exibido à esquerda Viewe aparece como um cubo oco com moldura amarela.)
  10. Selecione o método: closeKeyboard.
  11. Execute o programa.

Agora, quando você clicar em qualquer lugar no plano de fundo View, poderá descartar o teclado.

Espero que isso ajude a resolver seu problema. :-)


2

Eu modifiquei a solução de Bryan para ser um pouco mais robusta, para que ela funcionasse bem com outros tipos de teclados que poderiam aparecer na mesma exibição. Está descrito aqui:

Criar um botão CONCLUÍDO na interface do usuário do teclado numérico do iOS

Eu tentaria explicá-lo aqui, mas a maioria é de código para olhar que não caberia facilmente aqui


Esta foi a melhor solução que encontrei para o XCode 4.5 e funciona com o iOS 6.0. Ele adiciona um botão CONCLUÍDO ao teclado numérico. Vá para a postagem original para obter os gráficos dos botões CONCLUÍDOS. neoos.ch/blog/…
birdman

2

Se você souber com antecedência o número de números a serem inseridos (por exemplo, um PIN de 4 dígitos), poderá ignorar automaticamente após 4 pressionamentos de tecla, conforme minha resposta a essa pergunta semelhante:

demitindo o teclado numérico

Não há necessidade de um botão pronto adicional neste caso.


2

Também podemos simplificar ainda mais a solução "o usuário tocou em outro lugar" , se apenas dissermos à visão do nosso view controller para terminar a edição:

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

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

... assumindo que "tocar em outro lugar dispensa o teclado" é o comportamento desejado para outros campos editáveis ​​na exibição também.


1

Para o Swift 2.2, eu uso este

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

0

Todas essas implementações sobre como encontrar a visualização do teclado e adicionar o botão concluído na 3ª linha (é por isso que button.y = 163 b / c de altura do teclado é 216) são frágeis porque o iOS continua alterando a hierarquia da visualização. Por exemplo, nenhum dos códigos acima funciona para iOS9.

Eu acho que é mais seguro encontrar a visualização superior, por [[[UIApplication sharedApplication] windows] lastObject], e basta adicionar o botão no canto inferior esquerdo dela, doneButton.frame = CGRectMake (0, SCREEN_HEIGHT-53, 106 , 53); // modo retrato


0

Swift 2.2 / Eu usei a resposta de Dx_. No entanto, eu queria essa funcionalidade em todos os teclados. Então, na minha classe base, eu coloquei o 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)
        }
    }
}

Em seguida, basta chamar addDoneButtonForTextFields em self.view.subviews em viewDidLoad (ou willDisplayCell se estiver usando uma exibição de tabela) para adicionar o botão Concluído a todos os teclados.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.