2016-07-19 36 views
0

我有一个UIView子类(MyView),其中包含UITextView。我想MyView使用UITextView所有UIResponder方法,像这样:通过包含另一个firstResponder(一个UITextView)制作firstResponder UIView

@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认为MyViewfirstResponder。然而,由于我在-[MyView becomeFirstResponder]内依次拨打-[UITextView becomeFirstResponder],其中一个必须赢,一个必须输。哪个赢,哪个输?如果UITextViewfirstResponder,那么为什么-[MyView isFirstResponder]曾经返回YES

有没有人有任何建议?我的上述实施是否正确?

回答

0

虽然我找到了other evidence that people solved this problem the same way。这个实现导致我的问题。 TLDR:我认为你只是不应该编写UIResponder对象。

我的错误:

  1. 消费者呼吁MyView的方法,并MyView编程调用-[UITextView becomeFirstResponder]。没有人在MyView的内部UITextView上点击。
  2. 消费者想要关闭键盘。我们可以验证UITextViewfirstResponder,因为私有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. 用户点击MyViewUITextView
  2. 消费者要解雇键盘。我们可以验证UITextViewfirstResponder,因为私有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对象。

- 编辑 -

我仍然不知道肯定出了什么问题,但我发现我有多个UIWindow在我的应用程序,我已经从人们听到那些知道™:多窗口应用程序偶尔会有firstResponder问题。