Jak wyświetlić przycisk „Gotowe” na klawiaturze numerycznej iPhone'a

237

Na klawiaturze numerycznej nie ma przycisku „Gotowe”. Kiedy użytkownik kończy wprowadzanie informacji numerycznych w polu tekstowym, jak mogę usunąć klawiaturę numeryczną?

Mogłem uzyskać przycisk „Gotowe” za pomocą domyślnej klawiatury, ale wtedy użytkownicy musieliby przełączyć się na klawisze numeryczne, aby wprowadzić cyfry. Czy istnieje sposób wyświetlenia przycisku „Gotowe” na klawiaturze numerycznej?

Chilly Zhong
źródło

Odpowiedzi:

339

Inne rozwiązanie. Idealne, jeśli na ekranie znajdują się inne pola tekstowe inne niż klawisze numeryczne.

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
źródło
1
Bez wątpienia najlepszy sposób na osiągnięcie tego. Wyraźnie, ponieważ przestrzega ścisłego HIG Jabłka.
Hubert Kunnemeyer,
3
Drugie rozwiązanie jest bardzo kruche pod względem jakichkolwiek zmian graficznych w klawiaturze ekranowej, które je złamią.
kailoon 30.01.2013
Jeśli istnieje wiele pól tekstowych, jak ustalić, które pole UITextField jest edytowane?
Nate
Zdefiniuj swój UITextField w .h jako zmienną instancji.
Luda
3
@ BenPotter Ustawiłbyś barTint dla koloru paska i koloru odcienia dla tekstu. Można również utworzyć elementy UIBarButton po stronie inicjatora i ustawić dla nich kolor.
ocross
50

Oto adaptacja odpowiedzi Ludy na Swift:

W deklaracji swojej podklasy UIViewController umieść

let numberToolbar: UIToolbar = UIToolbar()

w ViewDidLoad umieść:

    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 

i dodaj funkcje hoopla i hoopla (możesz swobodnie wybierać inne nazwy, wystarczy odpowiednio zmienić nazwy selektora w ViewDidLoad

func boopla () {
    textField.resignFirstResponder()
}

func hoopla () {
    textField.text=""
    textField.resignFirstResponder()
}
użytkownik1258240
źródło
1
UIBarButtonItemStyle.Borderedjest przestarzałe od iOS 8.0. UIBarButtonItemStyle.Plainzamiast tego jest sugerowane.
Jonny,
Selektory należy zaktualizować do: #selector (YourViewController.boopla)
David V
Jonny i David prawdopodobnie mają rację. Nie programuję już dla iOS, więc nie śledzę zmian. Jeśli ktoś opublikuje zaktualizowane rozwiązanie, odwołam się do niego w edycji.
user1258240,
14

Sztuczka, którą widziałem, polega na stworzeniu niestandardowego przezroczystego przycisku wielkości całego widoku, a następnie w metodzie kliknięcia, aby pole tekstowe zrezygnowało z pierwszej odpowiedzi. Użytkownik może kliknąć dowolne miejsce poza polem, aby zamknąć klawiaturę.

davidavr
źródło
3
Zrobiłem to oprócz klawisza Return. To sprawia, że ​​aplikacja jest znacznie bardziej przyjazna dla użytkownika. Lubię podawać zarówno klucze powrotu, jak i metody zwrotu w dowolnym miejscu.
IcyBlueRose
4
teraz, gdy mamy UIGestureRecognizers, po prostu skonfiguruj rozpoznawanie gestów dotknij w głównym widoku kontrolera widoku i niech wyśle ​​endEdycja: TAK, aby wyświetlić. Spowoduje to zamknięcie klawiatury dla każdego pola tekstowego, które klawiatura może obsługiwać, dotykając poza klawiaturą.
chadbag
14

Rozwiązanie Swift 3 przy użyciu rozszerzenia. Idealny, jeśli masz UITextFieldw aplikacji kilka obiektów numerycznych, ponieważ daje to swobodę decydowania dla każdego UITextField, czy wykonać niestandardową akcję po dotknięciu Gotowe lub Anuluj .

wprowadź opis zdjęcia tutaj

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

Przykład użycia z użyciem domyślnych działań:

//
// MyViewController.swift
//

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

Przykład użycia z użyciem niestandardowej czynności Gotowe :

//
// MyViewController.swift
//

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

func doneButtonTappedForMyNumericTextField() { 
    print("Done"); 
    myNumericTextField.resignFirstResponder() 
}
oli
źródło
12

Poniżej znajduje się przegląd odpowiedzi Ludy z następującymi zmianami:

  • widok akcesoriów jest automatycznie dopasowywany do szerokości ramki aplikacji

  • UIBarButtonItemStyleBorderedunika się przestarzałej stałej

  • przycisk „Gotowe” jest tworzony jako UIBarButtonSystemItemDone

Obecnie przycisk „Gotowe” jest wyśrodkowany w widoku akcesoriów. Możesz ustawić go po lewej lub prawej stronie, usuwając spację po odpowiedniej stronie.

Pominąłem przycisk „Anuluj”, ponieważ domyślna klawiatura też go nie ma. Jeśli chcesz przycisk „Anuluj”, sugeruję utworzenie go jako a UIBarButtonSystemItemCanceloraz upewnienie się, że nie odrzucasz oryginalnej wartości w polu tekstowym. Zachowanie „Anuluj” zaimplementowane w odpowiedzi Ludy, które zastępuje wartość pustym ciągiem, może nie być tym, czego chcesz.

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

Aby uzyskać więcej informacji na temat tworzenia widoków akcesoriów, zobacz dokumentację Apple dotyczącą niestandardowych widoków wprowadzania danych . Prawdopodobnie będziesz chciał również zajrzeć na strony referencyjne na UIToolbar i UIBarButtonItem .

Michael Laszlo
źródło
[UIScreen mainScreen].applicationFramejest przestarzałe w iOS 9. Użyj[UIScreen mainScreen].bounds
user-44651
11

Rozwiązanie w UIKeyboardTypeNumberPad i brakujący klawisz powrotu działa świetnie, ale tylko wtedy, gdy na ekranie nie ma innych pól tekstowych innych niż klawisze numeryczne.

Wziąłem ten kod i przekształciłem go w kontroler UIViewController, który możesz po prostu podklasować, aby klawisze numeryczne działały. Będziesz musiał pobrać ikony z powyższego linku.

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

i 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

Cieszyć się.

Archie
źródło
6

Oto najnowszy kod. Po prostu dołącz #import „UIViewController + NumPadReturn.h” do swojego viewController.

Oto .h

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

@interface UIViewController (NumPadReturn)



@end

I oni

#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
źródło
wydaje się, że działa to na symulatorze, ale na urządzeniu ... ani nie widzę przycisku GOTOWE, ani nic się nie dzieje po dotknięciu pustej przestrzeni ... jakiś pomysł?
xoail
14
Wow, nie używaj tego kodu. Przesłaniasz metody klasowe z kategorii, co spowoduje, że „prawdziwy” viewDidLoad itp. Z twojej klasy UIViewController zostanie zignorowany.
Tony Arnold,
6

O wiele łatwiejsze rozwiązanie

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

    [textViewInstance1 resignFirstResponder];
    [textViewInstance2 resignFirstResponder];
    [textField resignFirstResponder];
}
Govind
źródło
5

Jeśli masz wiele pól numerycznych, sugeruję podklasowanie UITextField, aby utworzyć NumericTextField, który zawsze wyświetla klawiaturę numeryczną z wykonanym przyciskiem. Następnie po prostu powiąż pola numeryczne z tą klasą w Konstruktorze interfejsów i nie będziesz potrzebować dodatkowego kodu w żadnym ze swoich kontrolerów widoku. Oto klasa Swift 3.0, której używam w 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()
    }
}

Szybki 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
źródło
Wolę twoje podklasowe rozwiązanie.
AechoLiu,
5

Uważam, że odpowiedź @ user1258240 jest dość zwięzła, ponieważ nie jest to tak proste, jak ustawienie returnKeyTypewłaściwości.

Chciałem po prostu wnieść do tego własne podejście „wielokrotnego użytku”:

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
źródło
3

SWIFT 3.0 Inny smak, wykorzystujący fragmenty niektórych poprzednich odpowiedzi.

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
źródło
2

Opisuję tutaj jedno rozwiązanie dla iOS 4.2+ , ale przycisk odrzucania znika po pojawieniu się klawiatury. To nie jest straszne, ale też nie idealne.

Rozwiązanie opisane w pytaniu połączonym powyżej zawiera bardziej elegancką iluzję, aby zwolnić przycisk, w której zanikam i przesuwam w pionie przycisk, aby uzyskać wrażenie, że klawiatura i przycisk zwalniają się razem.

FluffulousChimp
źródło
2

Najprostszym sposobem jest:

Tworzenie niestandardowych przezroczysty przycisk i umieść go w lewym dolnym rogu, które będą miały taki sam CGSizejak w pustej przestrzeni UIKeyboardTypeNumberPad. Przełącz (pokaż / ukryj) ten przycisk w polu tekstowym becomeFirstResponder, odpowiednio po kliknięciu przycisku.

Almas Adilbek
źródło
2

Oto najprostsze rozwiązanie, z jakim się zetknąłem. Nauczyłem się tego z książki Początek rozwoju iOS 5.

Zakładając, że pole numeru jest wywoływane numberField.

  1. W ViewControllerdodaj następującą metodę:

    -(IBAction)closeKeyboard:(id)sender;
  2. W ViewController.mdodaj następujący kod:

    -(IBAction)closeKeyboard:(id)sender
    {
    
         [numberField resignFirstResponder];
    
    }
  3. Wróć do nibpliku.

  4. Otwórz Utilitiespatelnię.
  5. Otwórz Identity inspectorpod Utilitiespatelnię.
  6. Kliknij raz View(w pliku stalówki). Upewnij się, że nie kliknąłeś żadnego elementu w widoku. Dla wyjaśnienia, powinieneś zobaczyć UIView pod Classw Identity inspector.
  7. Zmień klasę z UIView na UIControl.
  8. Otwarte Connection Inspector.
  9. Kliknij i przeciągnij Touch Downi upuść strzałkę na File Ownerikonę. (FYI ... Ikona właściciela pliku jest wyświetlana po lewej stronie Viewi pojawia się jako pusta kostka z żółtą ramką.)
  10. Wybierz metodę: closeKeyboard.
  11. Uruchom program.

Teraz, gdy klikniesz gdziekolwiek w tle View, powinieneś być w stanie zwolnić klawiaturę.

Mam nadzieję, że pomoże to rozwiązać problem. :-)

Rutvij Kotecha
źródło
2

Zmodyfikowałem rozwiązanie Bryana, aby było trochę bardziej niezawodne, aby działało ładnie z innymi typami klawiatur, które mogłyby pojawiać się w tym samym widoku. Jest to opisane tutaj:

Utwórz przycisk GOTOWE na klawiaturze numerycznej UIKeyboard na iOS

Spróbuję to wyjaśnić tutaj, ale większość z nich to kod do sprawdzenia, który łatwo by się tutaj nie zmieścił

podkowa 7
źródło
To było najlepsze rozwiązanie, które znalazłem dla XCode 4.5 i działa ono z iOS 6.0. Dodaje przycisk GOTOWE do klawiatury numerycznej. Przejdź do oryginalnego postu, aby uzyskać grafikę przycisku GOTOWE. neoos.ch/blog/…
birdman
2

Jeśli znasz z góry liczbę cyfr, które należy wprowadzić (np. 4-cyfrowy kod PIN), możesz automatycznie odrzucić po 4 naciśnięciach klawiszy, zgodnie z moją odpowiedzią na to podobne pytanie:

zwalnianie klawiatury numerycznej

W tym przypadku nie ma potrzeby używania dodatkowego przycisku.

scipilot
źródło
2

Możemy również uprościć rozwiązanie „dotknięty użytkownik gdzie indziej” , jeśli po prostu powiemy naszemu kontrolerowi widoku, aby zakończył edytowanie:

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

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

... zakładając, że „dotykanie gdzie indziej powoduje wyłączenie klawiatury” jest pożądanym zachowaniem również dla innych edytowalnych pól w widoku.

Sitric
źródło
1

W Swift 2.2 używam tego

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_
źródło
0

Wszystkie te implementacje dotyczące znajdowania widoku klawiatury i dodawania gotowego przycisku w trzecim rzędzie (dlatego button.y = 163 b / c wysokość klawiatury wynosi 216) są kruche, ponieważ iOS ciągle zmienia hierarchię widoku. Na przykład żaden z powyższych kodów nie działa w systemie iOS9.

Myślę, że bezpieczniej jest po prostu znaleźć najwyższy widok według [[[Windows [aplikacja współużytkowana przez UIApplication]]] LastObject] i po prostu dodać przycisk w lewym dolnym rogu, doneButton.frame = CGRectMake (0, SCREEN_HEIGHT-53, 106 , 53); // tryb pionowy

Qiulang
źródło
0

Swift 2.2 / Użyłem odpowiedzi Dx_. Chciałem jednak tę funkcję na wszystkich klawiaturach. Więc w mojej klasie bazowej umieściłem kod:

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

Następnie wystarczy wywołać addDoneButtonForTextFields na self.view.subviews w viewDidLoad (lub willDisplayCell, jeśli używasz widoku tabeli), aby dodać przycisk Gotowe do wszystkich klawiatur.

Jan
źródło