Come mostrare il pulsante “Fatto” sul tastierino numerico dell'iPhone


237

Non è presente il pulsante "Fine" sul tastierino numerico. Quando un utente termina di immettere informazioni numeriche in un campo di testo, come posso far scomparire il tastierino numerico?

Potrei ottenere un pulsante "Fine" utilizzando la tastiera predefinita, ma gli utenti dovrebbero passare ai tasti numerici per inserire i numeri. C'è un modo per mostrare un pulsante "Fine" sul tastierino numerico?

Risposte:


339

Un'altra soluzione. Perfetto se sullo schermo sono presenti altri campi di testo senza tastierino numerico.

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
Senza dubbio il modo migliore per raggiungere questo obiettivo. Esplicitamente perché aderisce a HIG rigoroso di Apple.
Hubert Kunnemeyer,

3
L'altra soluzione è molto fragile in termini di eventuali modifiche grafiche alla tastiera su schermo la romperanno.
Kailoon,

Se sono presenti più campi di testo, come posso determinare quale UITextField viene modificato?
Nate,

Definisci il tuo UITextField in .h come variabile di istanza.
Luda,

3
@BenPotter Dovresti impostare barTint per il colore della barra e il colore della tinta per il testo. È inoltre possibile creare gli elementi UIBarButton all'esterno dell'intializzatore e impostarne il colore in modo esplicito lì.
ocross,

50

Ecco un adattamento per la risposta di Luda per Swift:

Nella dichiarazione della sottoclasse UIViewController inserisci

let numberToolbar: UIToolbar = UIToolbar()

in ViewDidLoad inserisci:

    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 aggiungi le funzioni hoopla e hoopla (sentiti libero di scegliere altri nomi, basta cambiare i nomi dei selettori in ViewDidLoad di conseguenza

func boopla () {
    textField.resignFirstResponder()
}

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

1
UIBarButtonItemStyle.Borderedè obsoleto da iOS 8.0. UIBarButtonItemStyle.Plainè invece suggerito.
Jonny

I selettori devono essere aggiornati a: #selector (YourViewController.boopla)
David V

Jonny e David hanno probabilmente ragione. Non sto più programmando per iOS, quindi non seguo le modifiche. Se qualcuno pubblica una soluzione aggiornata, mi riferirò ad essa in una modifica.
user1258240

14

Il trucco che ho visto è quello di rendere un pulsante trasparente personalizzato delle dimensioni dell'intera vista e quindi nel suo metodo di clic, fare in modo che il campo di testo dimetta il primo risponditore. Quindi l'utente può fare clic in qualsiasi punto al di fuori del campo per chiudere la tastiera.


3
L'ho fatto in aggiunta al tasto Invio. Rende un'app molto più user-friendly. Mi piace fornire sia i tasti di ritorno sia i metodi di ritorno ovunque.
IcyBlueRose l'

4
ora che abbiamo UIGestureRecognizer, basta impostare un riconoscimento dei gesti di tocco nella vista principale del controller della vista e farlo inviare endEditing: SI alla sua vista. Questo chiuderà la tastiera per ogni campo di testo che potrebbe essere riparato dalla tastiera, quando si tocca fuori dalla tastiera.
Chadbag,

14

Una soluzione Swift 3 che utilizza un'estensione. Ideale se hai diversi UITextFieldoggetti numerici nella tua app in quanto offre la flessibilità di decidere, per ciascuno UITextField, se eseguire un'azione personalizzata quando si tocca Fine o Annulla .

inserisci qui la descrizione dell'immagine

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

Esempio di utilizzo utilizzando le azioni predefinite:

//
// MyViewController.swift
//

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

Esempio di utilizzo con un costume Done azione:

//
// MyViewController.swift
//

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

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

12

Di seguito una revisione della risposta di Luda con le seguenti modifiche:

  • la vista degli accessori viene automaticamente dimensionata in base alla larghezza del riquadro dell'applicazione

  • la costante deprecata UIBarButtonItemStyleBorderedviene evitata

  • il pulsante "Fine" è istanziato come a UIBarButtonSystemItemDone

Attualmente il pulsante "Fine" è centrato nella vista accessori. Puoi posizionarlo a sinistra o a destra eliminando lo spazio sul lato pertinente.

Ho omesso un pulsante "Annulla" perché la tastiera predefinita non ne ha nemmeno uno. Se vuoi un pulsante "Annulla", ti suggerisco UIBarButtonSystemItemCanceldi creare un'istanza come a e di assicurarti di non eliminare il valore originale nel campo di testo. Il comportamento "Annulla" implementato nella risposta di Luda, che sovrascrive il valore con una stringa vuota, potrebbe non essere quello che desideri.

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

Per ulteriori informazioni sulla creazione di viste degli accessori, consultare la documentazione Apple sulle viste personalizzate per l'immissione dei dati . Probabilmente vorrai consultare anche le pagine di riferimento su UIToolbar e UIBarButtonItem .


[UIScreen mainScreen].applicationFrameè obsoleto in iOS 9. Usa[UIScreen mainScreen].bounds
user-44651

11

La soluzione in UIKeyboardTypeNumberPad e la chiave di ritorno mancante funzionano alla grande, ma solo se sullo schermo non sono presenti altri campi di testo senza tastierino numerico.

Ho preso quel codice e l'ho trasformato in un UIViewController che puoi semplicemente sottoclassare per far funzionare i tastierino numerico. Dovrai ottenere le icone dal link sopra.

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

Godere.


6

Ecco il codice più recente. Includi semplicemente #import "UIViewController + NumPadReturn.h" nel tuo viewController.

Ecco il .h

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

@interface UIViewController (NumPadReturn)



@end

E loro

#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

questo sembra funzionare sul simulatore ma sul dispositivo ... né posso vedere il pulsante FATTO né succede nulla quando tocco lo spazio vuoto ... qualche idea?
xoail,

14
Wow, per favore non usare questo codice. Sostituisci i metodi di classe all'interno di una categoria, il che causerà l'ignorazione "reale" di viewDidLoad, ecc. Della tua classe UIViewController.
Tony Arnold,

6

Una soluzione molto più semplice

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

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

5

Se hai più campi numerici, ti suggerisco di sottoclassare UITextField per creare un NumericTextField che mostra sempre una tastiera numerica con un pulsante fatto. Quindi, associa semplicemente i tuoi campi numerici a questa classe in Interface Builder e non avrai bisogno di alcun codice aggiuntivo in nessuno dei tuoi controller di visualizzazione. Quella che segue è la classe Swift 3.0 che sto usando in 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()
    }
}

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

Preferisco la tua soluzione di sottoclasse.
AechoLiu,

5

Ho trovato la risposta di @utente1258240 abbastanza concisa dato che non è semplice come impostare una returnKeyTypeproprietà.

Volevo solo contribuire con il mio approccio "riutilizzabile" a questo:

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 Un sapore diverso, usando parti di alcune risposte precedenti.

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

Descrivo una soluzione per iOS 4.2+ qui, ma il pulsante di eliminazione svanisce dopo che appare la tastiera. Non è terribile, ma neanche ideale.

La soluzione descritta nella domanda sopra collegata include un'illusione più elegante per chiudere il pulsante, in cui dissolvenza e spostamento verticale del pulsante per dare l'impressione che la tastiera e il pulsante si stiano chiudendo insieme.


2

Il modo più semplice è:

creare un pulsante trasparente personalizzato e posizionarlo nell'angolo in basso a sinistra, che avrà lo stesso CGSizespazio vuoto in UIKeyboardTypeNumberPad. Attiva (mostra / nascondi) questo pulsante su textField becomeFirstResponder, facendo clic rispettivamente sul pulsante.


2

Ecco la soluzione più semplice che ho trovato. Ho imparato questo da Beginning iOS 5 Development book.

Supponendo che venga chiamato il campo numerico numberField.

  1. In ViewController, aggiungi il seguente metodo:

    -(IBAction)closeKeyboard:(id)sender;
  2. In ViewController.m, aggiungi il seguente codice:

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

  4. UtilitiesPadella aperta .
  5. Apri la padella Identity inspectorsottostante Utilities.
  6. Fare clic sul View(nel file pennino) una volta. Assicurati di non aver fatto clic su nessuno degli elementi nella vista. Per motivi di chiarezza, dovresti vedere UIView sotto Classin Identity inspector.
  7. Cambia la classe da UIView a UIControl.
  8. Aprire Connection Inspector.
  9. Fare clic e trascinare Touch Downe rilasciare la freccia File Ownersull'icona. (FYI ... L'icona del proprietario del file viene visualizzata a sinistra di Viewe appare come un cubo vuoto con cornice gialla.)
  10. Selezionare il metodo: closeKeyboard.
  11. Esegui il programma.

Ora, quando fai clic in un punto qualsiasi dello sfondo di View, dovresti essere in grado di chiudere la tastiera.

Spero che questo ti aiuti a risolvere il tuo problema. :-)


2

Ho modificato la soluzione di Bryan per renderla un po 'più robusta, in modo che potesse suonare bene con altri tipi di tastiere che potrebbero apparire nella stessa vista. È descritto qui:

Crea un pulsante FATTO sulla UIKeyboard del tastierino numerico iOS

Proverei a spiegarlo qui, ma la maggior parte è un codice da guardare che non si adatterebbe facilmente qui


Questa è stata la migliore soluzione che ho trovato per XCode 4.5 e funziona con iOS 6.0. Aggiunge un pulsante DONE alla tastiera numerica. Vai al post originale per ottenere la grafica del pulsante FATTO. neoos.ch/blog/…
birdman

2

Se si conosce in anticipo il numero di numeri da inserire (ad esempio un PIN di 4 cifre), è possibile chiudere automaticamente dopo 4 pressioni di tasti, come da mia risposta a questa domanda simile:

respingendo il tastierino numerico

Non è necessario un pulsante aggiuntivo fatto in questo caso.


2

Possiamo anche rendere la soluzione "utente toccato altrove" ancora più semplice se diciamo semplicemente alla vista del nostro controller di visualizzazione di terminare la modifica:

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

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

... supponendo che "toccare altrove ignori la tastiera" sia il comportamento desiderato anche per qualsiasi altro campo modificabile nella vista.


1

Per Swift 2.2 lo uso

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

Tutte quelle implementazioni sulla ricerca della vista della tastiera e l'aggiunta del pulsante Fine nella terza riga (ecco perché button.y = l'altezza della tastiera 163 b / c è 216) sono fragili perché iOS continua a cambiare la gerarchia della vista. Ad esempio nessuno dei codici precedenti funziona per iOS9.

Penso che sia più sicuro trovare la vista più in alto, di [[[UIApplication sharedApplication] windows] lastObject], e basta aggiungere il pulsante nell'angolo in basso a sinistra di esso, doneButton.frame = CGRectMake (0, SCREEN_HEIGHT-53, 106 , 53); // modalità ritratto


0

Swift 2.2 / Ho usato la risposta di Dx_. Tuttavia, volevo questa funzionalità su tutte le tastiere. Quindi nella mia classe base ho inserito il codice:

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

Quindi basta chiamare addDoneButtonForTextFields su self.view.subviews in viewDidLoad (o willDisplayCell se si utilizza una vista tabella) per aggiungere il pulsante Fine a tutte le tastiere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.