【问题标题】:How can I respond to touch events on a UITextField?如何响应 UITextField 上的触摸事件?
【发布时间】:2012-01-10 02:06:13
【问题描述】:

我想在UITextField 上响应触摸事件(特别是UIControlEventTouchUpInsideUIControlEventTouchUpOutside),但唯一通过的事件是UIControlEventTouchCancel

我不能使用UIControlEventEditingDidBegin,因为它只在字段获得焦点时发生,这不是我想要检测的。我想知道用户何时抬起手指,以及它是在文本字段的内部还是外部,无论当前的焦点状态如何。

有谁知道实现这一点的方法吗?

需要明确的是,我已经尝试使用 addTarget:action:forControlEvents,但它不起作用。取消阻止了触摸事件。我想要一种方法来检测 UITextField 消耗它并产生 Cancel 事件之前的修饰。

另外,如果可能的话,我想避免创建任何额外的视图。

【问题讨论】:

    标签: ios uitextfield


    【解决方案1】:

    一个关于这样做的方法是创建一个 UIButton,其填充设置为清除以覆盖所有空间,并在其顶部创建一个 UITextField。如果用户在文本域中触摸,文本域应该发送一个事件,如果用户在文本域之外触摸,UIButton 将发送事件。

    【讨论】:

    • 由于我无法通过触摸 TextField 内部来获取事件,因此这不起作用。如果可能的话,我还想避免创建任何额外的视图。
    【解决方案2】:

    这里的答案很好: Change default touch events for UITextField

    使用文本字段的委托,在 textFieldShouldBeginEditing 中做你想做的事:

    您可以返回 NO 以防止默认行为。

    【讨论】:

    • 这不是无用的信息,它可以帮助我更接近我想要的行为。不过,这不是一个完整的答案,因为它无法帮助我检测以UIControlEventTouchUpOutside 的方式在场内开始和结束于场外的触摸。
    • 这里要注意一点。该方法在更多情况下触发,而不仅仅是点击,例如在外部键盘上按 Tab 以遍历文本字段时。在 iOS 9 上测试。
    【解决方案3】:

    您可以为 UiView 创建类别并覆盖 touchesBegan 肉类,如下所示。

    它对我来说很好。它是这个问题的集中解决方案。

    #import "UIView+Keyboard.h"
    @implementation UIView(Keyboard)
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.window endEditing:true];
        [super touchesBegan:touches withEvent:event];
    }
    
    
    @end
    

    【讨论】:

      【解决方案4】:

      我今天刚遇到这个问题。我的目标是在触摸时更改文本字段的背景颜色,并在触摸/取消时将其恢复。 奇怪的是,从 UITextField 向目标发送了触摸,但内部触摸、外部触摸甚至触摸取消都没有。 我找到了解决方案。很简单。只需创建 UITextField 的子类并覆盖 touchesEnded: 和 touchesCancelled:。

      @interface TextField : UITextField
      
      @end
      
      @implementation CuteTextField
      
      - (id)initWithFrame:(CGRect)frame
      {
          self = [super initWithFrame:frame];
          if (self) {
              // Initialization code
          }
          return self;
      }
      
      -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
          [super touchesEnded:touches withEvent:event];
          self.backgroundColor=GetDefaultBackgroundColor();
      }
      
      -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
          [super touchesCancelled:touches withEvent:event];
          self.backgroundColor=GetDefaultBackgroundColor();
      }
      
      @end
      

      【讨论】:

        【解决方案5】:

        以编程方式为所需事件添加目标,或者使用 IB。

        UITextField * touchyTextField = [[UITextField alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 21.0)];
        
        [touchyTextField addTarget:self 
                            action:@selector(yourDesiredMethod) 
                  forControlEvents:UIControlEventTouchUpInside];
        

        【讨论】:

        • 不,这绝对行不通。我尝试的第一件事。永远不会调用“yourDesiredMethod”方法。我可以获取 UIControlEventTouchDown 的事件,但是两个 TouchUp 事件都没有被触发。相反,会触发 UIControlEventTouchCancel 事件。我也不能只将该事件用作我想要的事件的 hacky 代理,因为当长按显示放大循环以及其他取消用户输入(例如模式对话框或锁定屏幕)时也会触发它.
        • 哇,我认为它会像任何其他基于 UIView 的类一样工作。您也许可以创建一个自定义 UITextField 并覆盖 touchesBegan: 方法,确保在适当的情况下成为第一响应者,以便键盘仍然显示。
        • 所以,我尝试覆盖 touchesBegan/Ended/Cancelled,这也给了我一个 Began/Cancelled 对,没有 Ended 事件。这真是令人沮丧!此外,重写这些方法并没有阻止 textField 成为第一响应者,因此基类在我有机会之前就进行了触摸处理!
        • 您可以在 UITextFieldDelegate 中的 textFieldShouldBeginEditing 中处理内部修饰。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-28
        • 2018-08-06
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多