【问题标题】:Find View that is the firstresponder查找作为第一响应者的视图
【发布时间】:2012-03-26 15:00:59
【问题描述】:

我想获得作为第一响应者的视图,目前我有一个包含 UITextFields 的 UITableView,使用方法:

-(UIView*) findFirstResponder
{

}

我希望能够获得作为 firstResponder 的视图,然后使用该视图执行某些操作。

有什么想法吗?

【问题讨论】:

  • tableView 中有多少个 textField?
  • 它们是动态创建的,但我刚刚找到了一种方法
  • 很高兴知道这一点,只需将其发布为答案。 :)
  • 我建议尽可能远离 for 循环方法,这可能会增加不必要的处理。更简洁的方法是创建一个变量,本地或实例,以保存对活动对象的引用,通常在委托方法中设置,例如 UITextFieldDelegate 方法 - (void)textFieldDidBeginEditing:(UITextField *)textField.
  • 这实际上不是一个坏方法,我希望我能早点想到这一点,哦,现在我有一个可以演示的工作示例,我可以稍后再优化它。

标签: iphone ios first-responder


【解决方案1】:

我所要做的就是

@implementation UIView (FindViewThatIsFirstResponder)
- (UIView *)findViewThatIsFirstResponder
{
    if (self.isFirstResponder) {        
        return self;     
    }

    for (UIView *subView in self.subviews) {
        UIView *firstResponder = [subView findViewThatIsFirstResponder];
        if (firstResponder != nil) {
            return firstResponder;
        }
    }

    return nil;
}
@end

【讨论】:

  • 您不需要 textField 本身吗?子视图和带有textFields的表格有什么关系?
  • 详细说明为什么这对我有用:我有一个 UITextField,它有一个 UIPickerView 作为 inputView,现在这些都是动态创建的,所以我没有对任何字段的任何引用除了我的表格视图,所以当我选择一个文本字段时,UIPickerView 会显示出来,然后我在选择器中选择一个值来设置 UITextField 的文本,然后我必须调用一个委托方法将所选值传递回当前急救人员。看到这个问题stackoverflow.com/questions/9874037/…
【解决方案2】:

使用 UIControl 作为对可以成为第一响应者的不同类型控件的根引用。

UIControl *currentControl;

正如 Gobot 所说 - 每当文本字段成为第一响应者时,请记下它是哪一个...

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {   

    currentControl = textField;

    . . .

【讨论】:

  • Sheesh,所有这些其他解决方案都是荒谬的。这应该是所有类似问题的最佳答案:)
  • 如果第一响应者不是UITextField怎么办?还有UITextViews,也许还有其他人......?不要误会我的意思,对于所提出的问题,这是一个很好的解决方案,但我正在寻找更通用的东西。
  • 您可以使用对 UIControl 的引用。见上文
  • 这是迄今为止任何类似问题的最佳答案。
【解决方案3】:

在 iOS 中没有简单的方法可以找到 firstResponder。上面的答案仅跟踪UIViews,但UIResponder 的所有子类(例如UIViewController)都可以作为第一响应者。

根据UIResponderQuick Help

许多关键对象也是响应者,包括 UIApplication 对象、UIViewController 对象和所有 UIView 对象(其中 包括 UIWindow)。当事件发生时,UIKit 将它们分派给你的 应用的响应者对象进行处理。

而遵循UIResponder 链的唯一方法是使用UIRespondernext: UIResponder 属性。

返回响应者链中的下一个响应者,如果有则返回 nil 没有下一个响应者。 UIResponder 类不存储或设置 自动下一个响应者,所以这个方法默认返回 nil。 子类必须重写此方法并返回适当的 next 响应者。例如,UIView 实现了这个方法并返回 管理它的 UIViewController 对象(如果有的话)或其 superview(如果没有)。 UIViewController 类似地实现了 方法并返回其视图的父视图。 UIWindow 返回 应用对象。 UIApplication 返回 nil。

在大多数UIKit 对象中superviewUIViewControllerUIWindowUIApplicationAppdelegate 将是next UIResponder

extension UIResponder {
    func findFirstResponder() -> UIResponder? {
        var responder: UIResponder? = self
        while responder != nil {
            guard let r = responder, r.isFirstResponder else {
                responder = responder?.next
                continue
            }
            return r
        }
        return nil
    }
}

然而,上面没有跟踪responder 的兄弟姐妹。我想如果你真的想跟踪它们,你需要检查响应者的类型并跟踪它的子视图(子视图,子视图控制器)。

【讨论】:

  • 如何调用方法“findFirstResponder”?谢谢
【解决方案4】:

我想与您分享我在 UIView 的任何位置查找第一响应者的实现。我希望它对我的英语有所帮助和抱歉。谢谢

+ (UIView *) findFirstResponder:(UIView *) _view {
   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;
         }
      }
   }
}

【讨论】:

    【解决方案5】:

    我们可以利用以nil 为目标调用UIApplication.shared.sendAction 将操作发送给第一响应者这一事实。

    斯威夫特

    extension UIResponder {
        
        private static weak var _firstResponder: UIResponder?
        
        static var firstResponder: UIResponder? {
            _firstResponder = nil
            // Tell the first responder to record itself in `_firstResponder`
            UIApplication.shared.sendAction(#selector(_recordFirstResponder), to: nil, from: nil, for: nil)
            return _firstResponder
        }
        
        @objc private func _recordFirstResponder() {
            UIResponder._firstResponder = self
        }
        
    }
    

    然后只需访问UIResponder.firstReponder 就会给我们第一响应者。

    目标-C

    static __weak id foundFirstResponder;
    
    @implementation UIResponder (FindFirstResponder)
    
    +(id)firstResponder {
        foundFirstResponder = nil;
        [UIApplication.sharedApplication sendAction:@selector(findFirstResponder) to:nil from:nil forEvent:nil];
        return foundFirstResponder;
    }
    
    -(void)findFirstResponder {
        foundFirstResponder = self;
    }
    @end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多