2016-07-19 11 views
0

Ich habe eine UIView Unterklasse (MyView), die eine UITextView enthält. Ich möchte MyViewUITextView für alle UIResponder Methoden verwenden, etwa so:Machen Sie eine erste UIView-Antwort, indem Sie einen anderen firstResponder (eine 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 

Aber, wie ich durch Apple's Event Delivery: The Responder Chain documentation gerade lese, denke ich, kann dies eine falsche Umsetzung sein. Ich kann keine Dokumentation oder Beiträge darüber finden, wie man eine UIResponder mit einer anderen UIResponder erstellen kann.

UIKit hat eine Vorstellung von genau 1 firstResponder, so dass, wenn MyView-becomeFirstResponder Griffe und gibt YES, scheint es vernünftig, für UIKit zu denken MyView die firstResponder ist. Da ich aber wiederum -[UITextView becomeFirstResponder] innerhalb -[MyView becomeFirstResponder] anrufe, muss einer der beiden gewinnen und man muss verlieren. Welche gewinnt und welche verliert? Wenn UITextView die firstResponder ist, warum sollte -[MyView isFirstResponder] jemals YES zurückgeben?

Hat jemand einen Rat? Ist meine obige Implementierung korrekt?

Antwort

0

Obwohl ich other evidence that people solved this problem the same way gefunden. Diese Implementierung bereitet mir Probleme. TLDR: Ich denke, du solltest einfach keine UIResponder Objekte schreiben.

Mein Fehler:

  1. Ein Verbraucher ruft eine Methode auf MyView und MyView ruft programmatisch -[UITextView becomeFirstResponder]. Niemand klopft jemals auf MyView 's interne UITextView.
  2. Ein Verbraucher möchte die Tastatur ablehnen. Wir können überprüfen, dass UITextView die firstResponder ist, weil die private API -[UIApplication.sharedApplication.keyWindow firstResponder]UITextView zurückgibt.
  3. Ein Consumer ruft [UIApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil], aber dieser Aufruf gibt NO zurück. Während dieser Anruf getätigt wird, ruft UIKit nicht -[UITextView canPerformAction:withSender:] oder -[UITextView targetForAction:withSender:].

Wenn jedoch stattdessen:

  1. der Benutzer tippt auf MyView ‚s UITextView
  2. Ein Verbraucher möchte die Tastatur entlassen. Wir können überprüfen, dass UITextView die firstResponder ist, weil die private API -[UIApplication.sharedApplication.keyWindow firstResponder]UITextView zurückgibt.
  3. Ein Verbraucher ruft [UIApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil], und jetzt gibt dieser Anruf YES zurück. Während dieser Anruf erfolgt, ruft UIKit-[UITextView canPerformAction:withSender:] und -[UITextView targetForAction:withSender:] wie erwartet auf, und ruft dann natürlich -[UITextView resignFirstResponder], was erfolgreich ist.

Ich habe keine Ahnung, warum im ersten Fall [UIApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil] nicht richtig UITextView delegiert, aber ich muss, dass es ohne zu [super becomeFirstResponder] Delegieren seit -[MyView becomeFirstResponder] nehmen wie die Docs sagen, habe etwas durcheinander. Ich denke, du solltest einfach keine UIResponder Objekte komponieren.

--EDIT--

ich sicher noch nicht wissen, was los ist, aber ich entdeckte, dass ich mehrere UIWindow s in meiner app, und ich habe von Menschen, die wissen ™ gehört, dass Multi-Fenster-Apps können gelegentlich firstResponder Probleme haben.

Verwandte Themen