获取当前的第一响应者而不使用私人API

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

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

现在,有问题的API调用实际上是我在SO上找到的解决方案:

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

我如何在屏幕上获得当前的第一响应者? 我正在寻找一种不会让我的应用遭到拒绝的方式。


在我的一个应用程序中,如果用户点击背景,我经常希望第一响应者辞职。 为此,我在UIView上写了一个类,我在UIWindow上调用它。

以下是基于此,并应返回第一响应者。

@implementation UIView (FindFirstResponder)
- (id)findFirstResponder
{
    if (self.isFirstResponder) {
        return self;        
    }
    for (UIView *subView in self.subviews) {
        id responder = [subView findFirstResponder];
        if (responder) return responder;
    }
    return nil;
}
@end

iOS 7+

- (id)findFirstResponder
{
    if (self.isFirstResponder) {
        return self;
    }
    for (UIView *subView in self.view.subviews) {
        if ([subView isFirstResponder]) {
            return subView;
        }
    }
    return nil;
}

迅速:

extension UIView {
    var firstResponder: UIView? {
        guard !isFirstResponder else { return self }

        for subview in subviews {
            if let firstResponder = subview.firstResponder {
                return firstResponder
            }
        }

        return nil
    }
}

Swift中的使用示例:

if let firstResponder = view.window?.firstResponder {
    // do something with `firstResponder`
}

如果你的最终目的只是[self.view endEditing:YES]第一响应者,这应该工作: [self.view endEditing:YES]


操纵第一响应者的常用方式是使用无针对性的动作。 这是一种向响应者链发送任意消息的方法(从第一响应者开始),然后继续下去直到有人响应消息(已经实现了与选择器匹配的方法)。

对于解除键盘的情况,无论哪个窗口或视图是第一响应者,这都是最有效的方式:

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

这应该比[self.view.window endEditing:YES]更有效。

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

链接地址: http://www.djcxy.com/p/44251.html

上一篇: Get the current first responder without using a private API

下一篇: Giving UIView rounded corners