Найти вид, который является первым ответчиком - PullRequest
8 голосов
/ 26 марта 2012

Я хотел бы получить представление, которое является первым респондентом, в настоящее время у меня есть UITableView, который содержит UITextFields, используя метод:

-(UIView*) findFirstResponder
{

}

Я хотел бы иметь возможность получить представление, являющееся первым ответчиком, а затем что-то сделать с этим представлением.

Есть идеи?

Ответы [ 4 ]

18 голосов
/ 26 марта 2012

Все, что мне нужно было сделать, это

@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
14 голосов
/ 26 марта 2012

Используйте UIControl в качестве корневой ссылки на различные типы элементов управления, которые могут стать первым респондентом.

UIControl *currentControl;

Как говорит Гобот - всякий раз, когда текстовое поле становится первым респондентом, запишите, какое оно есть ...

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

    currentControl = textField;

    . . .
1 голос
/ 11 августа 2017

Нет простого способа найти firstResponder в iOS.Ответы выше только отслеживания UIView с, но все подклассы UIResponder, такие как UIViewController могут быть первыми респондентом.

В соответствии с Quick Help из UIResponder:

Многие ключевые объекты также являются респондентами, включая объект UIApplication, объекты UIViewController и все объекты UIView (включая UIWindow).Когда происходят события, UIKit отправляет их объектам респондента вашего приложения для обработки.

И единственный способ следовать цепочке UIResponder - использовать свойство UIResponder next: UIResponder.

Возвращает следующего респондента в цепочке респондентов или ноль, если следующего респондента нет.Класс UIResponder не сохраняет и не устанавливает следующий респондент автоматически, поэтому этот метод возвращает nil по умолчанию.Подклассы должны переопределить этот метод и вернуть соответствующий следующий респондент.Например, UIView реализует этот метод и возвращает объект UIViewController, который управляет им (если он есть) или его суперпредставлением (если это не так).UIViewController аналогичным образом реализует метод и возвращает суперпредставление своего представления.UIWindow возвращает объект приложения.UIApplication возвращает nil.

В большинстве UIKit объект superview, UIViewController, UIWindow, UIApplication или Appdelegate будет 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.Я думаю, что если вы действительно хотите отслеживать их все, вам нужно проверить тип респондента и отследить его дочерний элемент (подпредставление, контроллер дочернего представления).

0 голосов
/ 22 сентября 2015

Я хотел бы поделиться с вами своей реализацией для поиска первого респондента в любом месте 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;
         }
      }
   }
}
...