2016-07-19 14 views
0

У меня есть UIView подкласс (MyView), который содержит UITextView. Я хочу MyView использовать UITextView для всех UIResponder методов, как так:Сделайте первый идентификатор URiewResponder, содержащий другой firstResponder (UITextView)

@implementation MyView 

- (BOOL)canBecomeFirstResponder { 
    return _textView.canBecomeFirstResponder 
} 
- (BOOL)becomeFirstResponder { 
    return [_textView becomeFirstResponder]; 
} 
- (BOOL)canResignFirstResponder { 
    return [_textView canResignFirstResponder]; 
} 
- (BOOL)resignFirstResponder { 
    // UIResponder documentation says [super resignFirstResponder] 
    // must be called somewhere in this method 
    BOOL superResignedFirstResponder = [super resignFirstResponder]; 
    if (superResignedFirstResponder) { 
    return [_textView resignFirstResponder]; 
    } else { 
    return NO; 
    } 
} 
- (BOOL)isFirstResponder { 
    return [_textView isFirstResponder]; 
} 

@end 

Однако, как я читаю через Apple's Event Delivery: The Responder Chain documentation, я думаю, что это может быть неправильное выполнение. Я не могу найти никакой документации или сообщений о том, как создать UIResponder с другим UIResponder.

UIKit имеет понятие ровно 1 firstResponder, поэтому, когда MyView обрабатывает -becomeFirstResponder и возвращает YES, представляется разумным для UIKit думать MyView является firstResponder. Однако, поскольку я, в свою очередь, звоню -[UITextView becomeFirstResponder] в пределах -[MyView becomeFirstResponder], один из двух должен выиграть, и один должен проиграть. Кто побеждает и который проигрывает? Если UITextView является firstResponder, то почему должно -[MyView isFirstResponder] когда-либо вернуть YES?

У кого-нибудь есть совет? Является ли моя реализация выше правильной?

ответ

0

Хотя я нашел other evidence that people solved this problem the same way. Эта реализация вызывает у меня проблемы. TLDR: Думаю, вы просто не должны составлять объекты UIResponder.

Моя ошибка:

  1. Потребитель вызывает метод на MyView и MyView программно вызывает -[UITextView becomeFirstResponder]. Никто никогда не набирает MyView внутренний номер UITextView.
  2. Потребитель хочет убрать клавиатуру. Мы можем проверить, что UITextView является firstResponder, потому что частный API -[UIApplication.sharedApplication.keyWindow firstResponder] возвращает UITextView.
  3. Потребитель звонит [UIApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil], но этот звонок возвращает NO. Пока этот вызов сделан, UIKit не вызывает -[UITextView canPerformAction:withSender:] или -[UITextView targetForAction:withSender:].

Однако, если вместо того, чтобы:

  1. пользователь нажимает на MyView «s UITextView
  2. Потребитель хочет, чтобы закрыть клавиатуру. Мы можем проверить, что UITextView является firstResponder, потому что частный API -[UIApplication.sharedApplication.keyWindow firstResponder] возвращает UITextView.
  3. Потребитель звонит [UIApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil], и теперь этот звонок возвращает YES. Пока этот вызов сделан, UIKit звонит -[UITextView canPerformAction:withSender:] и -[UITextView targetForAction:withSender:], как и ожидалось, а затем, конечно, звонит -[UITextView resignFirstResponder], который преуспевает.

Я понятия не имею, почему в первом случае [UIApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil] не делегировать UITextView должным образом, но я должен предположить, что с -[MyView becomeFirstResponder] без делегирования [super becomeFirstResponder] как документы говорят, что-то получил перепутались. Я думаю, вы просто не должны составлять объекты UIResponder.

--EDIT--

Я до сих пор не знаю точно, что это неправильно, но я обнаружил, что у меня есть несколько UIWindow с в моем приложении, и я слышал от людей, которые знают, что ™ многооконные приложения могут иметь случайные firstResponder вопросов.