我在一个多星期前提交了应用,今天收到了可怕的拒绝邮件。它告诉我,我的应用程序不能被接受,因为我使用的是非公共API;具体来说,它说,

应用程序中包含的非公共API是firstResponder。

现在,违规的API调用实际上是一个解决方案,我发现这里的SO:

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView   *firstResponder = [keyWindow performSelector:@selector(firstResponder)];

如何在屏幕上显示当前的第一响应器?我正在寻找一种不会让我的应用程序被拒绝的方法。


当前回答

你也可以这样尝试:

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event { 

    for (id textField in self.view.subviews) {

        if ([textField isKindOfClass:[UITextField class]] && [textField isFirstResponder]) {
            [textField resignFirstResponder];
        }
    }
} 

我没有试过,但这似乎是个不错的解决办法

其他回答

操作第一响应器的常用方法是使用nil目标操作。这是一种向响应器链发送任意消息的方式(从第一个响应器开始),并沿着链继续向下,直到有人响应消息(已经实现了与选择器匹配的方法)。

对于取消键盘的情况,这是最有效的方法,无论哪个窗口或视图是第一响应器:

[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

这应该比[self.view]更有效。窗口endEditing:是的)。

(感谢BigZaphod提醒我这个概念)

如果你只需要在用户点击背景区域时杀死键盘,为什么不添加一个手势识别器,并使用它来发送[[self view] enditing:YES]消息?

你可以在xib或storyboard文件中添加Tap手势识别器,并将其连接到一个动作,

看起来像这样,然后完成

- (IBAction)displayGestureForTapRecognizer:(UITapGestureRecognizer *)recognizer{
     [[self view] endEditing:YES];
}

这是我所做的,当用户单击ModalViewController中的Save/Cancel时,找到什么UITextField是第一个responder:

    NSArray *subviews = [self.tableView subviews];

for (id cell in subviews ) 
{
    if ([cell isKindOfClass:[UITableViewCell class]]) 
    {
        UITableViewCell *aCell = cell;
        NSArray *cellContentViews = [[aCell contentView] subviews];
        for (id textField in cellContentViews) 
        {
            if ([textField isKindOfClass:[UITextField class]]) 
            {
                UITextField *theTextField = textField;
                if ([theTextField isFirstResponder]) {
                    [theTextField resignFirstResponder];
                }

            }
        }

    }

}

Peter Steinberger刚刚发了关于私有通知UIWindowFirstResponderDidChangeNotification的推特,如果你想观察firstResponder的变化,你可以观察。

我想和你们分享我的实现,在UIView的任何地方找到第一个响应者。我希望这对我的英语有所帮助,对不起。谢谢

+ (UIView *) findFirstResponder:(UIView *) _view {

    UIView *retorno;

    for (id subView in _view.subviews) {

        if ([subView isFirstResponder])
        return subView;

        if ([subView isKindOfClass:[UIView class]]) {
            UIView *v = subView;

            if ([v.subviews count] > 0) {
                retorno = [self findFirstResponder:v];
                if ([retorno isFirstResponder]) {
                    return retorno;
                }
            }
        }
    }

    return retorno;
}