【问题标题】:Why calling [self becomeFirstResponder] caused so many problems?为什么调用 [self becomeFirstResponder] 会引起这么多问题?
【发布时间】:2011-10-14 15:29:37
【问题描述】:

在过去的几天里,我的生活非常令人沮丧,我一直在试图找出我的代码出了什么问题。在某个页面中,如果我输入 UITextViewsUITextFieldsMFMailComposer 或 MessageComposer 或任何需要编辑的字段,则这些字段不会响应触摸。运行应用程序时,我无法编辑任何内容。我无法编辑文本视图或电子邮件字段或任何东西。我尝试了一切,但没有任何效果。事实证明,在导致字段不响应的页面(GiftVC)的主页(MainVC)上,在viewDidAppear方法中(在MainVC中),我说:[self becomeFirstResponder]; .

现在我不太确定我为什么要把它放在那里,但事实证明,注释该行可以解决所有问题,并使所有字段、文本视图和电子邮件编辑器以及一切都再次正常工作。

我在MainVC 页面中也有这个:

-(BOOL)canBecomeFirstResponder {
    return YES;
}

并将其注释掉也可以解决问题。

奇怪的是,即使使用 [self becomeFirstResponder] 行,在新的 iOS 5(模拟器和设备)中一切正常,但在 iOS 4(模拟器和设备)中,它根本无法使用线。现在我已经删除了它,它在两种情况下都可以正常工作。

【问题讨论】:

    标签: iphone objective-c ios ios5


    【解决方案1】:

    如果你的 UIViewController 子类中有以下内容

    - (BOOL)canBecomeFirstResponder
    {
        return YES;
    }
    
    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        if (self.view.window) {
            [self becomeFirstResponder];
        }
    }
    

    那么您可能打算允许该子类处理运动事件(摇晃)或类似的事情。所以这可能就是它存在的原因。

    如果您无法编辑UITextFields,那么这个子类可能会成为第一响应者,而不是将事件转发给实际的UITextField。当UIViewController 子类调用覆盖canBecomeFirstResponder 以返回YES 并使它们自己成为第一响应者(即[self becomeFirstResponder],如果您不想让该自定义类处理UITextField 的触摸事件,那么你应该重写nextResponder 方法。

    我自己的产品中的一个例子——基本上我有一个UIViewController 子类,它做了两件事:1)它处理抖动事件,2)当点击某个按钮时,它以模态方式显示另一个视图。在模态视图中有一些UITextFields。为了让我的UIViewController 子类将触摸事件转发到我的模态视图,我添加了以下内容:

    - (UIResponder *)nextResponder
    {
        if (!self.view.window) {
            // If the modal view is being displayed, forward events to it.
            return self.modalViewController;
        } else {
            // Allow the superclass to handle event.
            return [super nextResponder];
        }
    }
    

    这将适用于 iOS 4 和 5,以及任何一个 sdk。

    现在,在您的情况下,您显然不记得首先添加代码成为第一响应者,因此您不需要上述挂钩。不过,了解未来是件好事。

    回到您的实际问题——一旦您将 SDK 更新到 5,为什么不能在 iOS 4 上运行,但在 iOS 5 上可以运行? iOS 5 正在为你做一些事件转发,这就是它在那里工作的原因。一开始它不应该在 iOS 4 上运行。 Apple 修复了一些允许它在 4 上运行的错误,这就是它不再在 4 上运行的原因。

    我知道该问题已经接受了已接受的答案;我只是想澄清一下那里的任何混乱。

    【讨论】:

    • 嗨...我最近使用了您的建议来覆盖 nextResponder 并且效果很好...除了一个问题。每当我从另一个模态呈现模态时,它就会永远循环。我有一个在此模式中呈现模式的视图,用户可以点击一个按钮来打开图像选择器。当点击此按钮时,我将图像选择器呈现为模态(模态内的模态)。在这种情况下,nextResponder 将永远循环。我一直在努力解决这个问题,但无法弄清楚。有什么建议吗?
    【解决方案2】:

    检查 MainVC 是否有一个名为 canResignFirstResponder 的方法返回 NO(至少有时是这样)。如果是这样,那么一旦它成为第一响应者,它就不会让其他任何东西成为第一响应者,直到它从该方法返回 YES。 (所有的 UITextViews 等都必须成为待编辑的第一响应者。)

    实际上,只要在你的所有代码中查找 canResignFirstResponder 的所有位置,以防它位于超类或其他东西中。

    否则,阻止文本字段和视图可编辑的唯一方法可能是设置 userInteractionEnabled = NO,但由于它取决于 becomeFirstResponder 语句,因此更可能与 canResignFirstResponder 相关。

    【讨论】:

    • 不,我的代码中没有 canResignFirstResponder 的痕迹。但问题仍然存在——为什么这在 iOS 5 中不是问题,而是在 iOS 4 中?
    【解决方案3】:

    在 iOS 4 中,子类必须覆盖 canBecomeFirstResponder 才能成为第一响应者。也许这对于 iOS 5 有所不同,或者这是一个错误。

    【讨论】:

      【解决方案4】:

      试试这个, 确保您已添加 uiTextViewDelegate 和

      - (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
          NSLog(@"textViewShouldBeginEditing:");
          return YES;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-07-02
        • 2020-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-04
        • 2014-08-02
        相关资源
        最近更新 更多