objective-c 失去对 UITextView 的关注时隐藏键盘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1456120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hiding the Keyboard when losing focus on a UITextView
提问by tuzzolotron
So I have a UITextView that I'm using to allow the user to submit some text.
所以我有一个 UITextView,我用它来允许用户提交一些文本。
My problem is, I can't seem to figure out how to allow the user to 'Cancel' by tapping away from the UITextView.
我的问题是,我似乎无法弄清楚如何通过点击远离 UITextView 来允许用户“取消”。
回答by ohhorob
Simplifying tuzzolotron's answer: Where the following outlet is properly connected in your xib
简化tuzzolotron 的答案:以下插座在您的 xib 中正确连接的位置
IBOutlet UITextView *myTextView;
Use this in the view controller:
在视图控制器中使用它:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if ([myTextView isFirstResponder] && [touch view] != myTextView) {
[myTextView resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
}
A tap on the View Controller's View, outside of the Text View, will resign the first responder, closing the keyboard.
在文本视图之外点击视图控制器的视图,将退出第一响应者,关闭键盘。
回答by Sr.Richie
Another approach I used a lot when working with UITableViews, Searchbar and keyboard is this, I think you can apply it to text field
我在使用 UITableViews、Searchbar 和键盘时经常使用的另一种方法是,我认为您可以将其应用于文本字段
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];
gestureRecognizer.cancelsTouchesInView = NO; // this prevents the gesture recognizers to 'block' touches
[gestureRecognizer release];
And then, here's the simple callback function
然后,这是简单的回调函数
- (void)hideKeyboard {
[myTextField resignFirstResponder];
}
Hope it helps
希望能帮助到你
回答by tuzzolotron
In my view:
在我看来:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
// pass touches up to viewController
[self.nextResponder touchesBegan:touches withEvent:event];
}
In my viewcontroller:
在我的视图控制器中:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if (keyboardShown && [touch view] != self.TextView)
{
[self.TextView resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
keyboardShown = YES;
}
回答by Carlos B
This is an old post, but I was implementing this solution when i found something a lot simpler (maybe it wasn't available back then).
这是一篇旧帖子,但是当我发现一些更简单的东西时,我正在实施这个解决方案(也许当时不可用)。
[self.myTextView endEditing:YES];
[self.myTextView endEditing:YES];
I'm using a UITableView, so I put this line on the didSelectRowAtIndexPath: method. So far, so good...
我正在使用 UITableView,所以我将这一行放在 didSelectRowAtIndexPath: 方法上。到现在为止还挺好...
回答by atomic_ice
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
var touch = event.allTouches()?.anyObject() as UITouch
if( textfield.isFirstResponder() && touch.view != textfield) {
textfield.resignFirstResponder()
NSLog("Resigning first responder since touches began outside")
}
super.touchesBegan(touches, withEvent: event)
}
ohhorob's answer worked for me too. Here's the simple swift equivalent.
ohhorob 的回答对我也有用。这是简单的 swift 等价物。
回答by mythicalcoder
Here is the swift 3 code
这是 swift 3 代码
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
if textField.isFirstResponder && touch.view != textField {
textField.resignFirstResponder()
}
}
super.touchesBegan(touches, with: event)
}
回答by Yas T.
Here is a better solution that does not depend upon an outlet and is going to work with any number of UITextField objects in your controller.
这是一个更好的解决方案,它不依赖于插座,并且将在您的控制器中使用任意数量的 UITextField 对象。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if (![[touch view] isKindOfClass:[UITextField class]]) {
[self.view endEditing:YES];
}
[super touchesBegan:touches withEvent:event];
}
回答by MaxEcho
Very easy
好简单
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
回答by Stefano Vettorazzi
My way to do it...
我的方法是...
Add a reference to the TextView in the @interface of your ViewController:
@property (weak, nonatomic) IBOutlet UITextView *yourTextView;Override this method in the @implementation of your ViewController:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { if ([self.yourTextView isFirstResponder]) { [self.yourTextView resignFirstResponder]; } }
在 ViewController 的 @interface 中添加对 TextView 的引用:
@property (weak, nonatomic) IBOutlet UITextView *yourTextView;在你的 ViewController 的 @implementation 中重写这个方法:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { if ([self.yourTextView isFirstResponder]) { [self.yourTextView resignFirstResponder]; } }
回答by David Jeske
I wanted a version of this that worked for resigning from any view, without requiring specific outlets for each one.. Here is my solution, which I put into one of my standard container views..
我想要一个可以从任何视图辞职的版本,而不需要每个视图都有特定的出口..这是我的解决方案,我将其放入我的一个标准容器视图中..
It's using MonoTouch C#, though it should be obvious how to convert it to Objective-C
它使用 MonoTouch C#,不过如何将其转换为 Objective-C 应该很明显
private void findAndResignFirstResponder(UIView node=null) {
if (node == null) { return; }
if (node.IsFirstResponder) {
node.ResignFirstResponder();
return;
}
foreach (UIView view in node.Subviews) {
findAndResignFirstResponder(node:view);
}
}
private bool haveDrag = false;
public override void TouchesEnded(NSSet touches, UIEvent evt) {
if (!haveDrag) {
UITouch touch = (UITouch)evt.AllTouches.AnyObject;
if (!touch.View.CanBecomeFirstResponder) {
this.findAndResignFirstResponder(this);
Console.WriteLine("resign");
}
}
base.TouchesEnded (touches, evt);
}
public override void TouchesMoved(NSSet touches, UIEvent evt) {
haveDrag = true;
base.TouchesMoved (touches, evt);
}
public override void TouchesBegan(NSSet touches, UIEvent evt) {
haveDrag = false;
base.TouchesBegan (touches, evt);
}

