在. numberpad键盘类型上没有“完成”按钮。当用户在文本字段中输入数字信息时,如何使数字pad消失?

我可以使用默认键盘来获得“完成”按钮,但用户必须切换到数字键才能输入数字。有没有办法在数字板上显示“完成”按钮?


当前回答

一个更简单的解决方案

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

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

其他回答

如果你有多个数字字段,我建议子类化UITextField来创建一个NumericTextField,它总是显示一个带有done按钮的数字键盘。然后,简单地将你的数值字段与接口构建器中的这个类关联起来,你就不需要在任何视图控制器中添加任何额外的代码。下面是我在Xcode 8.0中使用的Swift 3.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()
    }
}

斯威夫特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()
    }
}

Swift 2.2 /我用了Dx_的答案。然而,我希望所有的键盘都有这个功能。所以在我的基类中,我把代码:

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

然后只需调用addDoneButtonForTextFields在self.view.subviews在viewDidLoad(或willDisplayCell如果使用表格视图)添加完成按钮到所有键盘。

我所见过的技巧是创建一个与整个视图大小相同的自定义透明按钮,然后在其click方法中,让文本字段辞去first responder。因此,用户可以单击字段之外的任何地方来取消键盘。

在UIKeyboardTypeNumberPad和缺少返回键的解决方案很好,但只有当屏幕上没有其他非数字pad文本字段时。

我把这段代码变成一个UIViewController你可以简单地子类化它来让数字垫工作。您需要从上面的链接获取图标。

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

和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

享受。

如果我们告诉视图控制器的视图结束编辑,我们也可以让“user touched somewhere else”解决方案更简单:

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

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

... 假设“触摸其他地方会取消键盘”是视图中任何其他可编辑字段所期望的行为。