Tôi đang tự hỏi làm thế nào để làm cho bàn phím biến mất khi người dùng chạm vào bên ngoài a UITextField
.
Tôi đang tự hỏi làm thế nào để làm cho bàn phím biến mất khi người dùng chạm vào bên ngoài a UITextField
.
Câu trả lời:
Bạn sẽ cần thêm UITapGestureRecogniser
và gán nó vào dạng xem, sau đó gọi từ chức trả lời đầu tiên trên UITextField
bộ chọn.
Mật mã:
Trong viewDidLoad
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
Trong bỏ qua:
-(void)dismissKeyboard
{
[aTextField resignFirstResponder];
}
(Trường hợp aTextField
văn bản chịu trách nhiệm cho bàn phím)
Phiên bản Swift 3 trông như thế
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
Để loại bỏ
func dismissKeyboard (_ sender: UITapGestureRecognizer) {
aTextField.resignFirstResponder()
}
[aTextField resignFirstResponder]
là [self.view endEditing:YES];
nó không cần tham chiếu đến trường văn bản và sẽ hoạt động cho nhiều trường văn bản
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(endEditing:)]];
[tap setCancelsTouchesInView:NO];
câu trả lời của @qiaoyi; Tôi gặp vấn đề với một bảng không đáp ứng với các lựa chọn hàng. 5 năm sau, tôi hy vọng điều này sẽ giúp người khác.
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
Tôi nghiền ngẫm một vài câu trả lời.
Sử dụng một chiếc ngà được khởi tạo trong thời gian viewDidLoad:
UIGestureRecognizer *tapper;
- (void)viewDidLoad
{
[super viewDidLoad];
tapper = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSingleTap:)];
tapper.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapper];
}
Loại bỏ những gì hiện đang chỉnh sửa:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Kiểm tra cái này, đây sẽ là cách dễ nhất để làm điều đó,
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];// this will do the trick
}
Hoặc là
Thư viện này sẽ xử lý bao gồm cuộn tự động cuộn, chạm vào không gian để ẩn bàn phím, v.v ...
Tôi thấy rằng một số người đang gặp vấn đề khi sử dụng UITapGestureRecognizer
phương pháp này. Cách dễ nhất mà tôi đã hoàn thành chức năng này trong khi vẫn giữ nguyên hành vi nhấn nút hiện tại của mình là chỉ thêm một dòng vào câu trả lời của @ Jensen2k:
[tap setCancelsTouchesInView:NO];
Điều này cho phép các nút hiện tại của tôi vẫn hoạt động mà không cần sử dụng phương pháp của @Dmitry Sitnikov.
Đọc về điều đó property
ở đây (tìm kiếm CancelsTouchesInView
): Tham khảo lớp UIGestureRecognizer
Tôi không chắc nó sẽ hoạt động như thế nào với thanh cuộn, vì tôi thấy một số vấn đề xảy ra, nhưng hy vọng ai đó có thể gặp phải kịch bản tương tự mà tôi có.
UIImageView
, thêm [imageView setUserInteractionEnabled:NO];
và bạn "nhấp qua" nó, làm cho phương pháp này hoạt động.
Nó là tốt hơn để làm cho của bạn UIView
một thểUIControl
(trong trình xây dựng giao diện) và sau đó kết nối TouchUpInside
sự kiện của họ với dismissKeyboard
phương thức. Đây IBAction
phương pháp sẽ giống như sau:
- (IBAction)dismissKeyboard:(id)sender {
[aTextBox resignFirstResponder];
}
UITapGestureRecognizer
can thiệp vào việc nhấn vào các nút bên trong chế độ xem). touchesEnded
đã không hoạt động vì có sự UIScrollView
lộn xộn với chuỗi phản hồi.)
Swift 4
Thiết lập của bạn UIViewController
với phương thức mở rộng này một lần, ví dụ viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
self.setupHideKeyboardOnTap()
}
và bàn phím sẽ bị loại bỏ ngay cả khi nhấn vào NavigationBar
.
import UIKit
extension UIViewController {
/// Call this once to dismiss open keyboards by tapping anywhere in the view controller
func setupHideKeyboardOnTap() {
self.view.addGestureRecognizer(self.endEditingRecognizer())
self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
}
/// Dismisses the keyboard from self.view
private func endEditingRecognizer() -> UIGestureRecognizer {
let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
tap.cancelsTouchesInView = false
return tap
}
}
Phiên bản Swift, phiên bản này hoạt động kết hợp với các yếu tố khác (như một UIButton
hoặc khác UITextField
):
override func viewDidLoad() {
super.viewDidLoad()
let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
tapper.cancelsTouchesInView = false
view.addGestureRecognizer(tapper)
}
self
hơnself.view
canclesTouchesInView
là một tài sản tiện dụng để sử dụng. Cảm ơn.
c#
. FYI Dấu chấm phẩy đó là cho phép cú pháp, nó chỉ không cần thiết.
Làm thế nào về điều này: Tôi biết đây là một bài viết cũ. Nó có thể giúp ai đó :)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *subviews = [self.view subviews];
for (id objects in subviews) {
if ([objects isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objects;
if ([objects isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
Đây là một giải pháp chung tốt:
Mục tiêu-C:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Nhanh:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
Dựa trên giải pháp @icodebuster: https://stackoverflow.com/a/18756253/417652
Swift 4 oneliner
view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
Tôi nghĩ cách dễ nhất (và tốt nhất) để làm điều này là phân lớp chế độ xem toàn cầu của bạn và sử dụng hitTest:withEvent
phương pháp để lắng nghe bất kỳ liên lạc nào. Chạm vào bàn phím chưa được đăng ký, vì vậy hitTest: withEvent chỉ được gọi khi bạn chạm / cuộn / vuốt / véo ... ở một nơi khác, sau đó gọi [self endEditing:YES]
.
Điều này tốt hơn so với việc sử dụng touchesBegan
vì touchesBegan
không được gọi nếu bạn nhấp vào nút trên đầu chế độ xem. Nó tốt hơn là UITapGestureRecognizer
không thể nhận ra một cử chỉ cuộn chẳng hạn. Nó cũng tốt hơn so với sử dụng màn hình mờ vì trong giao diện người dùng phức tạp và năng động, bạn không thể đặt màn hình mờ ở mọi nơi. Hơn nữa, nó không chặn các hành động khác, bạn không cần nhấn hai lần để chọn nút bên ngoài (như trong trường hợp a UIPopover
).
Ngoài ra, tốt hơn là gọi [textField resignFirstResponder]
, bởi vì bạn có thể có nhiều trường văn bản trên màn hình, vì vậy điều này hoạt động cho tất cả chúng.
Đây phải là cách dễ nhất để ẩn bàn phím của bạn bằng cách chạm vào bên ngoài:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
(từ Cách tắt bàn phím khi người dùng chạm vào khu vực khác ngoài trường văn bản? )
Nếu chế độ xem được nhúng hoàn toàn trong một UIScrollView
thì bạn có thể sử dụng như sau:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Cái trước sẽ làm động bàn phím tắt màn hình khi chế độ xem bảng được cuộn và cái sau sẽ ẩn bàn phím giống như ứng dụng Tin nhắn chứng khoán.
Lưu ý rằng những thứ này có sẵn trên iOS 7.0 trở lên.
Bạn có thể làm điều này bằng cách sử dụng Storyboard trong XCode 6 trở lên:
Thêm phần này vào tệp tiêu đề của lớp được sử dụng bởi ViewContoder của bạn:
@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>
- (IBAction)dissmissKeyboardOnTap:(id)sender;
@end
Sau đó thêm phần này vào tệp triển khai của cùng một ViewContoder:
- (IBAction)dissmissKeyboardOnTap:(id)sender{
[[self view]endEditing:YES];
}
Bây giờ đây sẽ là một trong những 'Hành động đã nhận' cho cảnh trên bảng phân cảnh của bạn (ví dụ: ViewContoder):
Bây giờ bạn cần nối hành động này với cử chỉ của người dùng khi chạm vào bàn phím.
Quan trọng - Bạn cần chuyển đổi 'UIView' có trong bảng phân cảnh của mình thành UIControl , để nó có thể nhận các sự kiện. Chọn chế độ xem từ phân cấp Cảnh điều khiển Chế độ xem của bạn:
... và thay đổi lớp của nó:
Bây giờ kéo từ vòng tròn nhỏ bên cạnh 'hành động đã nhận' cho cảnh của bạn, vào phần 'trống' trong cảnh của bạn (thực ra bạn đang kéo 'Hành động đã nhận' vào UIControl). Bạn sẽ được hiển thị một lựa chọn các sự kiện mà bạn có thể kết nối hành động của mình để:
Chọn tùy chọn 'chạm lên bên trong'. Bây giờ bạn đã nối IBAction mà bạn đã tạo cho hành động người dùng chạm vào bàn phím. Khi người dùng gõ bàn phím, nó sẽ bị ẩn.
(LƯU Ý: Để nối hành động với sự kiện, bạn cũng có thể kéo trực tiếp từ hành động đã nhận vào UIControl trong phân cấp Bộ điều khiển Chế độ xem của bạn. Nó được hiển thị dưới dạng 'Điều khiển' trong cấu trúc phân cấp.)
Nếu tôi hiểu đúng về bạn, bạn muốn từ chức bàn phím sẽ chạm vào bên textfield
ngoài nhưng bạn không có tài liệu tham khảo textfield
.
Thử cái này;
reftextField
Bây giờ trong textFieldDidBeginEditing
trường văn bản được tham chiếu đến
- (void) textFieldDidBeginEditing:(UITextField *)textField{
reftextField = textField;
}
Bây giờ bạn có thể vui vẻ sử dụng trên bất kỳ đồng hồ nút nào, (thêm một nút trong suốt khi bắt đầu chỉnh sửa giới thiệu)
- (void)dismissKeyboard {
[reftextField resignFirstResponder];
}
Hoặc để từ chức nút thực hiện thử điều này.
//for resigning on done button
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Chỉ cần thêm vào danh sách ở đây phiên bản của tôi về cách loại bỏ bàn phím khi chạm bên ngoài.
viewDidLoad:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
Bất cứ nơi nào:
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[textFieldName resignFirstResponder];
puts("Dismissed the keyboard");
}
Rất nhiều câu trả lời tuyệt vời ở đây về việc sử dụng - tất cả UITapGestureRecognizer
trong số đó UITextField
là nút rõ ràng (X). Giải pháp là triệt tiêu bộ nhận dạng cử chỉ thông qua đại biểu của nó:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
return !(touchViewIsButton && touchSuperviewIsTextField);
}
Nó không phải là giải pháp mạnh mẽ nhất nhưng nó hiệu quả với tôi.
return !touchViewIsButton
. Tôi đoán bất kỳ nút nào khác cần tắt bàn phím nên thực hiện trong hành động của họ. Ngoài ra, TouchUpInside có thể không được gọi khi bố trí thay đổi khi loại bỏ bàn phím.
Bạn có thể tạo thể loại cho UiView và ghi đè lên biểu tượng cảm ứngBegan như sau.
Nó đang hoạt động tốt đối với tôi. Và nó là giải pháp tập trung cho vấn đề này.
#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.window endEditing:true];
[super touchesBegan:touches withEvent:event];
}
@end
Phiên bản Swift của câu trả lời của @ Jensen2k:
let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(gestureRecognizer)
func dismissKeyboard() {
aTextField.resignFirstResponder()
}
Lót
self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))
Tôi đã sử dụng ví dụ Barry cho sự phát triển mới của tôi. Nó đã làm việc tuyệt vời! nhưng tôi phải bao gồm một thay đổi nhỏ, yêu cầu chỉ tắt bàn phím đối với trường văn bản đang được chỉnh sửa.
Vì vậy, tôi đã thêm vào Barry ví dụ như sau:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
_textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
_textBeingEdited = nil;
}
Ngoài ra, tôi đã thay đổi phương thức hidePal như sau:
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
//UITextField * tf = (UITextField *) sender;
[_textBeingEdited resignFirstResponder];
}
Một trong những cách dễ nhất và ngắn nhất là thêm mã này vào viewDidLoad
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self.view
action:@selector(endEditing:)]];
Tôi đã thử nhiều câu trả lời ở đây và không gặp may. Trình nhận dạng cử chỉ nhấn của tôi luôn khiến tôi UIButtons
không phản hồi khi gõ, ngay cả khi tôi đặtcancelsTouchesInView
tính của trình nhận dạng cử chỉ thành KHÔNG.
Đây là những gì cuối cùng đã giải quyết vấn đề:
Có một chiếc ngà:
UITapGestureRecognizer *_keyboardDismissGestureRecognizer;
Khi một trường văn bản bắt đầu chỉnh sửa, hãy đặt trình nhận dạng cử chỉ:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
if(_keyboardDismissGestureRecognizer == nil)
{
_keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissKeyboard)] autorelease];
_keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
}
}
Sau đó, mẹo là cách bạn thiết lập dismissKeyboard
phương thức:
- (void) dismissKeyboard
{
[self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}
- (void) dismissKeyboardSelector
{
[self.view endEditing:YES];
[self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
_keyboardDismissGestureRecognizer = nil;
}
Tôi đoán chỉ có một cái gì đó về việc dismissKeyboardSelector
thực hiện ra khỏi ngăn thực thi xử lý cảm ứng ...
Gửi tin nhắn resignFirstResponder
đến textfiled mà đặt nó ở đó. Xin vui lòng xem bài viết này để biết thêm thông tin.
Trong ví dụ này, aTextField là UITextField duy nhất .... Nếu có những cái khác hoặc UITextViews, sẽ còn một chút nữa để làm.
// YourViewController.h
// ...
@interface YourViewController : UIViewController /* some subclass of UIViewController */ <UITextFieldDelegate> // <-- add this protocol
// ...
@end
// YourViewController.m
@interface YourViewController ()
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTapRecognizer;
@end
// ...
@implementation
@synthesize singleTapRecognizer = _singleTapRecognizer;
// ...
- (void)viewDidLoad
{
[super viewDidLoad];
// your other init code here
[self.view addGestureRecognizer:self.singleTapRecognizer];
{
- (UITapGestureRecognizer *)singleTapRecognizer
{
if (nil == _singleTapRecognizer) {
_singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToDismissKeyboard:)];
_singleTapRecognizer.cancelsTouchesInView = NO; // absolutely required, otherwise "tap" eats events.
}
return _singleTapRecognizer;
}
// Something inside this VC's view was tapped (except the navbar/toolbar)
- (void)singleTapToDismissKeyboard:(UITapGestureRecognizer *)sender
{
NSLog(@"singleTap");
[self hideKeyboard:sender];
}
// When the "Return" key is pressed on the on-screen keyboard, hide the keyboard.
// for protocol UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
NSLog(@"Return pressed");
[self hideKeyboard:textField];
return YES;
}
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
[aTextField resignFirstResponder];
NSLog(@"keyboard hidden");
}
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(handleSingleTap:)];
[singleTapGestureRecognizer setNumberOfTapsRequired:1];
[singleTapGestureRecognizer requireGestureRecognizerToFail:singleTapGestureRecognizer];
[self.view addGestureRecognizer:singleTapGestureRecognizer];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
[self.view endEditing:YES];
[textField resignFirstResponder];
[scrollView setContentOffset:CGPointMake(0, -40) animated:YES];
}
Thêm mã này vào tệp ViewControll.m của bạn :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
Trong trường hợp này, có thể sử dụng ScrollView và được thêm vào TextField
trong ScrollView và tôi muốn Chạm vào ScrollView
và Xem sau đó Loại bỏ Bàn phím. Tôi đã cố gắng tạo mã mẫu chỉ trong trường hợp. Như thế này,
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
view.addGestureRecognizer(tapGesture)
// Do any additional setup after loading the view, typically from a nib.
}
func tap(gesture: UITapGestureRecognizer) {
textField.resignFirstResponder()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Storyboard của bạn Nhìn vào đó giống như.
Bạn có thể sử dụng phương pháp UITapGestureRecongnizer để loại bỏ bàn phím bằng cách nhấp vào bên ngoài UITextField. Bằng cách sử dụng phương pháp này bất cứ khi nào người dùng sẽ nhấp bên ngoài UITextField thì bàn phím sẽ bị loại bỏ. Dưới đây là đoạn mã để sử dụng nó.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissk)];
[self.view addGestureRecognizer:tap];
//Method
- (void) dismissk
{
[abctextfield resignFirstResponder];
[deftextfield resignFirstResponder];
}