有什么方法可以询问 iOS 视图的哪个孩子具有第一响应者状态?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5029267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:54:41  来源:igfitidea点击:

Is there any way of asking an iOS view which of its children has first responder status?

ioscocoa-touchuiresponderresponder-chain

提问by Tommy Herbert

In Mac OS X, you can find the first responder like this:

在 Mac OS X 中,您可以像这样找到第一响应者:

[[self window] firstResponder]

Is there any way of doing it in iOS? Or do you need to enumerate the child controls and send an isFirstRespondermessage to each one?

有没有办法在iOS中做到这一点?还是需要枚举子控件isFirstResponder并向每个控件发送消息?

采纳答案by Evan Mulawski

You would need to iterate over all of the child controls and test the isFirstResponderproperty. When you encounter TRUE, break out of the loop.

您需要遍历所有子控件并测试该isFirstResponder属性。当你遇到时TRUE,跳出循环。

UIView *firstResponder;
for (UIView *view in self.view.subviews) //: caused error
{
    if (view.isFirstResponder)
    {
        firstResponder = view;
        break;
    }
}


BETTER SOLUTION

更好的解决方案

See Jakob's answer.

雅各布的回答

回答by Jakob Egger

I really like VJK's solution, but as MattDiPasquale suggests it seems more complex than necessary. So I wrote this simpler version:

我真的很喜欢VJK 的解决方案,但正如 MattDiPasquale 所暗示的那样,它似乎比必要的更复杂。所以我写了这个更简单的版本:

Objective-C

目标-C

#import "UIResponder+FirstResponder.h"

static __weak id currentFirstResponder;

@implementation UIResponder (FirstResponder)

+(id)currentFirstResponder {
    currentFirstResponder = nil;
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
    return currentFirstResponder;
}

-(void)findFirstResponder:(id)sender {
   currentFirstResponder = self;
}

@end

Swift 4

斯威夫特 4

import UIKit

extension UIResponder {

    private static weak var _currentFirstResponder: UIResponder?

    static var currentFirstResponder: UIResponder? {
        _currentFirstResponder = nil
        UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil)

        return _currentFirstResponder
    }

    @objc func findFirstResponder(_ sender: Any) {
        UIResponder._currentFirstResponder = self
    }
}

I also made it a class method since that seemed to make more sense. You can now find the first responder like so: [UIResponder currentFirstResponder]

我还把它变成了一个类方法,因为这似乎更有意义。您现在可以像这样找到第一响应者:[UIResponder currentFirstResponder]



回答by VJK

I wrote a category on UIResponderto find the first responder

我写了一个类别UIResponder来寻找第一响应者

@interface UIResponder (firstResponder)
- (id) currentFirstResponder;
@end

and

#import <objc/runtime.h>
#import "UIResponder+firstResponder.h"

static char const * const aKey = "first";

@implementation UIResponder (firstResponder)

- (id) currentFirstResponder {
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:self forEvent:nil];
    id obj = objc_getAssociatedObject (self, aKey);
    objc_setAssociatedObject (self, aKey, nil, OBJC_ASSOCIATION_ASSIGN);
    return obj;
}

- (void) setCurrentFirstResponder:(id) aResponder {
    objc_setAssociatedObject (self, aKey, aResponder, OBJC_ASSOCIATION_ASSIGN);
}

- (void) findFirstResponder:(id) sender {
    [sender setCurrentFirstResponder:self];
}

@end

Then in any class that derives from a UIResponderyou can get the first responder by calling

然后在派生自 a 的任何类中,UIResponder您都可以通过调用获得第一响应者

UIResponder* aFirstResponder = [self currentFirstResponder];

but remember to import the UIResponder category interface file first!

不过记得先导入UIResponder类接口文件!

This uses documented API's so there should be no app store rejection issues.

这使用了文档化的 API,因此应该没有应用商店拒绝问题。

回答by Praxiteles

If you need first responder just so you can ask it to resign its status, here is an approach to get any to resign. UIView has a method that will iterate through all of UIViews subviews and ask any that are first responder to resign.

如果您需要第一响应者只是为了让您可以要求其辞职,这里有一种方法可以让任何人辞职。UIView 有一个方法可以遍历所有 UIViews 子视图并要求任何第一响应者辞职。

[[self view] endEditing:YES];

Here is a link to Apple's UIView Docs"This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the text field is never even asked; it is forced to resign."

这是Apple 的 UIView Docs链接“此方法查看当前作为第一响应者的文本字段的当前视图及其子视图层次结构。如果找到,它会要求该文本字段辞去第一响应者的职务。如果强制参数设置为 YES,甚至从未询问过文本字段;它被迫辞职。”