2012-03-26 2 views
7

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

-(UIView*) findFirstResponder 
{ 

} 

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

Любые идеи?

+0

Сколько текстовых полей у вас есть в tableView? –

+0

Они динамически созданы, но я нашел способ только сейчас – Armand

+0

Рад это знать, просто опубликуйте его как ответ. :) –

ответ

17

Все, что я должен был сделать

@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 
+0

Вам не нужен сам textField? Какова связь между подвью и таблицей с текстовыми полями? – o15a3d4l11s2

+0

Чтобы более подробно узнать, почему это будет работать для меня: у меня есть UITextField, который имеет UIPickerView как inputView, теперь все они созданы динамически, поэтому я не отношусь к каким-либо ссылкам, кроме моего вида таблицы, поэтому, когда Я выбираю текстовое поле, которое отобразит UIPickerView, и затем я выбираю значение в сборщике, чтобы установить текст UITextField, после чего мне пришлось вызвать метод делегата, чтобы передать выбранное значение обратно текущему первому ответчику. см. этот вопрос http://stackoverflow.com/questions/9874037/uipickerview-and-uitextfield-get-value-from-uipickerview/ – Armand

+0

Хорошее решение;) – Emad

14

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

UIControl *currentControl; 

Как говорит Gobot - всякий раз, когда текстовое поле становится первым респондентом, держать ноту из которых один он ...

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

    currentControl = textField; 

    . . . 
+1

Sheesh, все эти другие решения смешны. Это должно быть верным ответом на все аналогичные вопросы :) – taylorcressy

+0

Что делать, если первый ответчик не является 'UITextField'? Есть 'UITextView' тоже, а может и другие ...? Не поймите меня неправильно, это прекрасное решение для заданного вопроса, но я ищу что-то более универсальное. – devios1

+0

Вы можете использовать ссылку на UIControl. См. Выше – Damo

0

Я хотел бы поделиться с вами своей реализации для поиска первого ответчика в в любом месте UIView. Надеюсь, это поможет и извините за мой английский. Thanks

+ (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; 
     } 
     } 
    } 
} 
1

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

Согласно Quick HelpUIResponder из:

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

И единственный способ следовать UIResponder цепи будет использовать UIResponder «s next: UIResponder свойства.

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

В большинстве UIKit объекта superview, UIViewController, UIWindow, UIApplication или Appdelegate будет nextUIResponder.

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 «S братьев и сестер. Я думаю, если вы действительно хотите отслеживать их все, вам нужно проверить тип ответчика и отслеживать его дочерний элемент (subview, child view controller).

Смежные вопросы