Cómo mostrar el button "Listo" en la almohadilla numérica de iPhone

No hay un button "Hecho" en el keyboard numérico. Cuando un usuario termina de ingresar información numérica en un campo de text, ¿cómo puedo hacer desaparecer el pad numérico?

Podría get un button "Listo" usando el keyboard pnetworkingeterminado, pero luego los usuarios tendrían que cambiar a las teclas numéricas para ingresar numbers. ¿Hay alguna forma de mostrar un button "Listo" en el keyboard numérico?

Otra solución. Perfecto si hay otros campos de text sin pad 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:UIBarButtonItemStyleBordenetworking 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]; } 

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

En la statement de su subclass UIViewController puesto

 let numberToolbar: UIToolbar = UIToolbar() 

en ViewDidLoad puesto:

  numberToolbar.barStyle = UIBarStyle.BlackTranslucent numberToolbar.items=[ UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Bordenetworking, target: self, action: "hoopla"), UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil), UIBarButtonItem(title: "Apply", style: UIBarButtonItemStyle.Bordenetworking, target: self, action: "boopla") ] numberToolbar.sizeToFit() textField.inputAccessoryView = numberToolbar //do it for every relevant textfield if there are more than one 

y agrega las funciones hoopla y hoopla (no dude en elegir otros nombres, simplemente cambie los nombres del selector en ViewDidLoad en consecuencia

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

El truco que he visto usado es hacer que un button transparente personalizado del tamaño de toda la vista y luego en su método de clic, haga que el campo de text renuncie al primer respondedor. Entonces, el usuario puede hacer clic en cualquier lugar fuera del campo para descartar el keyboard.

La solución en UIKeyboardTypeNumberPad y la tecla de retorno faltante funciona bien, pero solo si no hay otros campos de text de pad no numérico en la pantalla.

Tomé ese código y lo convertí en un UIViewController que simplemente puede subclass para que los pads numéricos funcionen. Deberá get los icons 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 shanetworkingApplication] windows] count] < 2) return; UIWindow *keyboardWindow = [[[UIApplication shanetworkingApplication] 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.

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

  • la constante en desuso UIBarButtonItemStyleBordenetworking se evita

  • el button "Listo" se ejemplifica como UIBarButtonSystemItemDone

Actualmente, el button "Listo" está centrado en la vista de accesorios. Puede colocarlo a la izquierda o la derecha borrando el espacio en el lado pertinente.

He omitido el button "Cancelar" porque el keyboard pnetworkingeterminado tampoco tiene uno. Si desea un button "Cancelar", sugiero que lo UIBarButtonSystemItemCancel como UIBarButtonSystemItemCancel y que se asegure de no descartar el valor original en el campo de text. 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 get más información sobre cómo crear vistas de accesorios, consulte la documentation de Apple en vistas personalizadas para la input de datos . Probablemente quiera consultar también las páginas de reference en UIToolbar y UIBarButtonItem .

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 shanetworkingApplication] 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 

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

Esta publicación del foro describe cómo personalizar UIKeyboard para agregar su vista personalizada al keyboard.

Describo una solución para iOS 4.2+ aquí, pero el button de rechazo se desvanece después de que aparezca el keyboard. No es terrible, pero tampoco ideal.

La solución que se describe en la pregunta vinculada anteriormente incluye una ilusión más elegante para descartar el button, donde se desvanecen y desplazan verticalmente el button para proporcionar la apariencia de que el keyboard y el button se despiden juntos.

La forma más simple es:

Cree un button transparente personalizado y colóquelo en la esquina inferior izquierda, que tendrá el mismo CGSize como espacio vacío en UIKeyboardTypeNumberPad . Toggle (show / hide) este button en textField becomeFirstResponder , en el button haga clic respectivamente.

Esta es la solución más simple que he encontrado. Lo he aprendido del libro de desarrollo de iOS 5 inicial.

Suponiendo que el campo de número se llama 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. Vuelva al file de nib .

  4. Abra la bandeja de Utilities .
  5. Abra el Identity inspector el Identity inspector Utilities .
  6. Haga clic en la View (en el file nib) una vez. Asegúrate de no haber hecho clic en ninguno de los elementos de la vista. En aras de la aclaración, debería ver UIView en Class in Identity inspector .
  7. Cambie la class de UIView a UIControl.
  8. Connection Inspector abierta.
  9. Haz clic y arrastra el cursor Touch Down y suelta la flecha en el ícono del File Owner . (FYI … El ícono de Propietario de file se muestra a la izquierda de View y aparece como un cubo hueco con marco amarillo.)
  10. Seleccione el método: closeKeyboard .
  11. Ejecuta el progtwig.

Ahora cuando hace clic en cualquier lugar en el background de View , debería poder descartar el keyboard.

Espero que esto te ayude a resolver tu problema. Todos los derechos reservados

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

Cree un button HECHO en el keyboard numérico de iOS UIKeyboard

Intentaría explicarlo aquí, pero la mayor parte es un código que no cabría fácilmente aquí.

Si sabe de antemano el número de numbers que debe ingresar (por ejemplo, un PIN de 4 dígitos), puede descartar automáticamente después de 4 pulsaciones de tecla, según mi respuesta a esta pregunta similar:

descartando la almohadilla numérica

No hay necesidad de un button adicional hecho en este caso.

También podemos hacer que la solución de "usuario tocado en otro lado" sea aún más sencilla si le decimos a la vista del controller de vista que termine de editar:

 -(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 "tocando en otro lugar descarta el keyboard" es el comportamiento deseado para cualquier otro campo editable en la vista también.

Para Swift 2.2 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() } 

Si tiene varios campos numéricos, sugiero subclassar UITextField para crear un NumericTextField que siempre muestra un keyboard numérico con un button hecho. Luego, simplemente asocie sus campos numéricos con esta class en el Generador de interfaces y no necesitará ningún código adicional en ninguno de sus Controladores de visualización. La siguiente es la class Swift 3.0 que estoy usando en Xcode 8.0.

 class NumericTextField: UITextField { let numericKbdToolbar = UIToolbar() // MARK: Initilization requinetworking 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() } } 

Encontré la respuesta de @ user1258240 para ser bastante concisa dado que esto no es tan simple como establecer una propiedad returnKeyType .

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

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

Una solución Swift 3 que usa una extensión. Ideal si tiene varios objects UITextField numéricos en su aplicación, ya que le da la flexibilidad de decidir, para cada UITextField , si realizar una acción personalizada cuando se UITextField Done o Cancel .

introduzca 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 pnetworkingeterminadas:

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

Ejemplo de uso con una acción Done personalizada:

 // // MyViewController.swift // @IBOutlet weak var myNumericTextField: UITextField! { didSet { myNumericTextField?.addDoneCancelToolbar(onDone: (target: self, action: #selector(doneButtonTappedForMyNumericTextField))) } } func doneButtonTappedForMyNumericTextField() { print("Done"); myNumericTextField.resignFirstResponder() } 

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

Todas esas implementaciones sobre la búsqueda de la vista del keyboard y la adición del button hecho en la 3ª fila (es por eso que la altura del keyboard button.y = 163b / c es 216) son frágiles porque iOS sigue cambiando 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 más alta, por [[[UIApplication shanetworkingApplication] windows] lastObject], y solo agrega el button en la esquina inferior izquierda de él, doneButton.frame = CGRectMake (0, SCREEN_HEIGHT-53, 106 , 53); // modo retrato

Swift 2.2 / Usé la respuesta de Dx_. Sin embargo, quería esta funcionalidad en todos los keyboards. Entonces, en mi class base puse 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 button Hecho a todos los keyboards.