【问题标题】:Hiding the Keyboard when losing focus on a UITextView失去对 UITextView 的关注时隐藏键盘
【发布时间】:2009-09-21 18:43:08
【问题描述】:

所以我有一个 UITextView 用于允许用户提交一些文本。

我的问题是,我似乎无法弄清楚如何通过点击 UITextView 来让用户“取消”。

【问题讨论】:

    标签: iphone objective-c cocoa-touch uikit uitextview


    【解决方案1】:

    简化tuzzolotron's answer: 在您的 xib 中正确连接以下插座的位置

        IBOutlet UITextView *myTextView;
    

    在视图控制器中使用它:

    - (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];
    }
    

    在文本视图之外点击视图控制器的视图,将使第一响应者退出,关闭键盘。

    【讨论】:

    • 如果这对他们不起作用,我很乐意帮助反对者。只需发表评论或提出新问题并在此处链接。
    • ohhorob,如果我们点击视图中的任何其他插座,此解决方案将不起作用,您能帮我解决这个问题吗?
    • 如果有人还在看这个...我有一个问题,我的根 VIEW 的大部分都被 UIScrollView 覆盖了。如果我直接在 UIView 上点击边距,键盘将关闭,但如果我点击该 UIScrollView,它不会。
    【解决方案2】:

    我在使用 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];
    

    然后,这里是简单的回调函数

    - (void)hideKeyboard {
        [myTextField resignFirstResponder];
    }
    

    希望对你有帮助

    【讨论】:

    • 如果您使用 ViewController,您可以添加到 [self view]。
    • 不行,表格和滚动视图有自己的交互作用
    • 这个答案是最好的。当我将 tapGestureRecognizer 添加到 self.view 时,它也适用于滚动视图中的一组文本字段
    • 这解决了问题。这里的关键是第三行,它允许其他触摸事件也发生(通过不阻塞)。它也适用于表格视图。 (在我的情况下,搜索栏位于表格视图单元格内,这不允许出口。在这种情况下,您可以使用self.view.endEditing(true) 而不是 resignFirstResponder。
    【解决方案3】:

    在我看来:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        UITouch *touch = [touches anyObject];
    
        // pass touches up to viewController
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    

    在我的视图控制器中:

    - (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;
    }
    

    【讨论】:

    • 如何将 touchesBegan 方法添加到 UITableView 中,该 UITableView 已经创建了我正在使用的 UIViewController 的 self.view 的子视图。我是否必须继承 UITableView,即@interface TouchableTableView : UITableView?或者,有没有更简单的方法来实现它,无需子类化 UITableView?
    【解决方案4】:

    这是一篇旧帖子,但当我发现一些更简单的东西时我正在实施这个解决方案(也许当时它不可用)。

    [self.myTextView endEditing:YES];

    我正在使用 UITableView,所以我将这一行放在 didSelectRowAtIndexPath: 方法上。 到目前为止,一切都很好......

    【讨论】:

      【解决方案5】:

      这是一个更好的解决方案,它不依赖于插座,并且可以与控制器中任意数量的 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];
      }
      

      【讨论】:

      • 不要认为你需要检查 UITextField - 即使你不加选择地endEditing:,在文本字段之间切换仍然有效,键盘确实保持不变
      【解决方案6】:
      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 的回答也对我有用。这是简单的 swift 等价物。

      【讨论】:

        【解决方案7】:

        这里是 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)
        }
        

        【讨论】:

          【解决方案8】:

          很简单

          -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
          {
              [self.view endEditing:YES];
          }
          

          【讨论】:

            【解决方案9】:

            我想要一个适用于从任何视图中退出的版本,而不需要为每个视图提供特定的出口。这是我的解决方案,我将其放入我的一个标准容器视图中。

            它使用的是 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);
                }
            

            【讨论】:

              【解决方案10】:

              我的方法...

              • 在 ViewController 的 @interface 中添加对 TextView 的引用:

                @property (weak, nonatomic) IBOutlet UITextView *yourTextView;
                
              • 在 ViewController 的 @implementation 中覆盖此方法:

                - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
                {
                    if ([self.yourTextView isFirstResponder]) {
                      [self.yourTextView resignFirstResponder];
                    }
                }
                

              【讨论】:

                猜你喜欢
                • 2015-02-22
                • 2012-07-16
                • 2011-11-20
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多