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

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

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

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

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


当前回答

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

其他回答

在UIResponder上有一个category,你可以合法地要求UIApplication对象告诉你谁是第一个responder。

看到这个:

有没有办法问一个iOS视图它的哪个子视图具有第一响应器状态?

遍历可能是第一响应器的视图,并使用- (BOOL)isFirstResponder来确定它们当前是否是。

这是递归的一个很好的候选!不需要添加一个类别到UIView。

用法(来自你的视图控制器):

UIView *firstResponder = [self findFirstResponder:[self view]];

代码:

// This is a recursive function
- (UIView *)findFirstResponder:(UIView *)view {

    if ([view isFirstResponder]) return view; // Base case

    for (UIView *subView in [view subviews]) {
        if ([self findFirstResponder:subView]) return subView; // Recursion
    }
    return nil;
}

我想和你们分享我的实现,在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;
}

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

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

看起来像这样,然后完成

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