为什么调用[self becomeFirstResponder]导致了这么多问题?

时间:2011-10-14 15:29:37

标签: iphone objective-c ios ios5

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

现在我不确定为什么我把它放在那里,但事实证明,评论该行可以修复所有内容并使所有字段和文本视图以及电子邮件作曲家和一切工作再次正常。

我也在MainVC页面中有这个:

-(BOOL)canBecomeFirstResponder {
    return YES;
}

并发表评论也解决了这个问题。

奇怪的是,即使使用[self becomeFirstResponder]行,一切都在新的iOS 5(模拟器和设备)中运行良好,但在iOS 4(模拟器和设备)中,它根本不起作用那条线。现在我删除了它,它在两种情况下都能正常工作。

4 个答案:

答案 0 :(得分:4)

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

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if (self.view.window) {
        [self becomeFirstResponder];
    }
}

然后您可能打算允许该子类处理运动事件(摇动)或类似的东西。所以这可能就是它的原因。

如果您无法编辑UITextField,则此子类可能成为第一个响应者,而不是将事件转发给实际的UITextField。当UIViewController子类调用覆盖canBecomeFirstResponder以返回YES并使它们成为第一个响应者(即[self becomeFirstResponder]时,如果您不希望该自定义类处理触摸UITextField的事件,然后您应该覆盖nextResponder方法。

我自己产品的一个例子 - 基本上我有一个UIViewController子类,可以做两件事:1)它处理震动事件; 2)当点击某个按钮时,它会以模态方式显示另一个视图。在模态视图中有一些UITextField。为了允许我的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的原因。

我知道这个问题已经接受了一个公认的答案;我只想清除那里的任何混乱。

答案 1 :(得分:3)

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

实际上只是查看canResignFirstResponder的所有代码中的任何位置,以防它在超类或其他内容。

否则唯一阻止文本字段和视图可编辑的东西可能是如果设置了userInteractionEnabled = NO,但由于它取决于becomeFirstResponder语句,因此更有可能使用canResignFirstResponder。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

试试这个,  确保添加了uiTextViewDelegate和

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