数字键盘上没有"完成"按钮.当用户完成在文本字段中输入数字信息时,如何使数字键盘消失?
我可以使用默认键盘获得"完成"按钮,但是用户必须切换到数字键才能输入数字.有没有办法在数字键盘上显示"完成"按钮?
另一种方法.如果屏幕上有其他非数字键盘文本字段,则非常完美.
- (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对Swift的回答的改编:
在你的UIViewController子类的声明中
let numberToolbar: UIToolbar = UIToolbar()
在ViewDidLoad中:
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
并添加函数hoopla和hoopla(随意选择其他名称,只需相应地更改ViewDidLoad中的选择器名称
func boopla () { textField.resignFirstResponder() } func hoopla () { textField.text="" textField.resignFirstResponder() }
我见过的技巧是制作一个自定义透明按钮,大小与整个视图相同,然后在其click方法中,让文本字段重新签名第一个响应者.因此,用户可以单击该字段外的任何位置来关闭键盘.
以下是对Luda的回答的改革,其中包括以下变化:
附件视图的大小自动调整为应用程序框架的宽度
弃用恒定UIBarButtonItemStyleBordered
避免
"完成"按钮被实例化为 UIBarButtonSystemItemDone
目前,"完成"按钮位于附件视图的中心.您可以通过删除相关侧的空间将其放置在左侧或右侧.
我省略了"取消"按钮,因为默认键盘也没有.如果你想要一个"取消"按钮,我建议你将它实例化为a UIBarButtonSystemItemCancel
,并确保你没有丢弃文本字段中的原始值.在Luda的答案中实现的"取消"行为可能不是您想要的,它会用空字符串覆盖该值.
- (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];
}
有关构建附件视图的更多信息,请参阅有关数据输入的自定义视图的Apple文档.您可能还想查阅UIToolbar和UIBarButtonItem上的参考页面.
甲夫特3溶液中使用的扩展.如果您UITextField
的应用程序中有多个数字对象,则可以灵活地为每个数字对象决定UITextField
是否在点击"完成"或" 取消"时执行自定义操作.
// // 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() } }
使用默认操作的使用示例:
// // MyViewController.swift // @IBOutlet weak var myNumericTextField: UITextField! { didSet { myNumericTextField?.addDoneCancelToolbar() } }
使用自定义完成操作的使用示例:
// // MyViewController.swift // @IBOutlet weak var myNumericTextField: UITextField! { didSet { myNumericTextField?.addDoneCancelToolbar(onDone: (target: self, action: #selector(doneButtonTappedForMyNumericTextField))) } } func doneButtonTappedForMyNumericTextField() { print("Done"); myNumericTextField.resignFirstResponder() }
UIKeyboardTypeNumberPad中的解决方案和丢失的返回键工作得很好,但前提是屏幕上没有其他非数字键盘文本字段.
我把这个代码转换成了一个UIViewController,您可以简单地将其子类化以使数字键盘工作.您需要从上面的链接中获取图标.
NumberPadViewController.h:
#import@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 ? @"请享用.
原始解决方案的链接现在重定向到http://www.neoos.ch/
7> Bryan..:这是最新的代码.只需在viewController中包含#import"UIViewController + NumPadReturn.h"即可.
这是.h
#import#import @interface UIViewController (NumPadReturn) @end 还有他们
#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:@"
哇,请不要使用此代码.您从类别中覆盖了类方法,这将导致忽略UIViewController类中的"真实"viewDidLoad等.
8> iGo..:一个更容易的解决方案
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; [textViewInstance1 resignFirstResponder]; [textViewInstance2 resignFirstResponder]; [textField resignFirstResponder]; }
9> 小智..:如果您有多个数字字段,建议将UITextField子类化以创建一个NumericTextField,该数字始终显示带有完成按钮的数字键盘。然后,只需将数字字段与此接口生成器中的此类相关联,您就不需要任何视图控制器中的任何其他代码。以下是我在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() } }
10> Matt..:我发现@ user1258240的答案非常简洁,因为这并不像设置
returnKeyType
属性那样简单。只是想为此贡献自己的“可重用”方法:
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) }