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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:14:07  来源:igfitidea点击:

Hiding the Keyboard when losing focus on a UITextView

iphoneobjective-ccocoa-touchuikituitextview

提问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);
    }