2012-03-26 10 views
7

Vorrei avere la vista che è il primo soccorritore, attualmente ho un UITableView che contiene UITextFields, utilizzando un metodo:Trova View che è il firstResponder

-(UIView*) findFirstResponder 
{ 

} 

Vorrei essere in grado di ottenere la vista che è il firstResponder e quindi fare qualcosa con quella vista.

Qualche idea?

+0

Quanti campi di testo sono presenti in TableView? –

+0

Sono creati dinamicamente ma ho trovato un modo solo ora – Armand

+0

Felice di saperlo, basta pubblicarlo come risposta. :) –

risposta

17

Tutto quello che dovevo fare era

@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

Non hai bisogno di textField? Qual è la relazione tra la sottoview e la tabella con i campi di testo? – o15a3d4l11s2

+0

Per approfondire il motivo per cui questo funzionerà per me: ho un UITextField che ha un UIPickerView come inputView, ora sono tutti creati dinamicamente quindi non ho alcun riferimento a nessun campo tranne la mia vista tabella, quindi quando Seleziono un campo di testo che verrà visualizzato UIPickerView e quindi seleziono un valore nel selettore per impostare il testo di UITextField, quindi ho dovuto chiamare un metodo delegato per passare nuovamente il valore selezionato al firstresponder corrente. vedi questa domanda http://stackoverflow.com/questions/9874037/uipickerview-and-uitextfield-get-value-from-uipickerview/ – Armand

+0

Bella soluzione;) – Emad

14

Usa UIControl come riferimento principale per diversi tipi di controllo che possono diventare first responder.

UIControl *currentControl; 

Come dice Gobot - ogni volta che un campo di testo diventa la prima responder, a mantenere una nota di cui uno è ...

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

    currentControl = textField; 

    . . . 
+1

Sheesh, tutte queste altre soluzioni sono ridicole. Questa dovrebbe essere la risposta migliore su tutte le altre domande :) – taylorcressy

+0

Cosa succede se il primo risponditore non è un 'UITextField'? Ci sono anche 'UITextView' e forse altri ...? Non fraintendetemi questa è una buona soluzione per la domanda posta, ma sto cercando qualcosa di un po 'più universale. – devios1

+0

È possibile utilizzare un riferimento a UIControl. Vedi sopra – Damo

0

vorrei condiviso con voi la mia implementazione per trovare first responder in ovunque su UIView. Spero che aiuti e mi dispiace per il mio inglese. Grazie

+ (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

Non c'è un modo semplice per trovare firstResponder in iOS. Le risposte di cui sopra sono solo di monitoraggio UIView s ma tutte le sottoclassi di UIResponder come UIViewController possono essere un primo risponditore.

Secondo la Quick Help di UIResponder:

Molti oggetti chiave sono inoltre intervento, inclusi l'oggetto UIApplication , oggetti UIViewController, e tutti gli oggetti UIView (che include UIWindow). Man mano che si verificano eventi, UIKit li invia agli oggetti risponditore della tua app per la gestione.

E l'unico modo per seguire UIResponder catena sarà utilizzando UIResponder s' next: UIResponder proprietà.

Restituisce il risponditore successivo nella catena di risposta o nulla se non c'è nessun risponditore successivo. La classe UIResponder non memorizza o imposta il risponditore automatico automaticamente, quindi questo metodo restituisce nil per impostazione predefinita. Le sottoclassi devono sovrascrivere questo metodo e restituire un rispondente appropriato successivo a . Ad esempio, UIView implementa questo metodo e restituisce l'oggetto UIViewController che lo gestisce (se ne ha uno) o la sua superview (in caso contrario). UIViewController implementa in modo simile il metodo e restituisce la superview della vista. UIWindow restituisce l'oggetto applicazione . L'applicazione UIA restituisce zero.

Nella più UIKit oggetto superview, UIViewController, UIWindow, UIApplication o Appdelegate sarà il 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 
    } 
} 

Tuttavia quanto sopra non si fa traccia responder 's fratelli. Suppongo che se vuoi davvero tenerne traccia, devi controllare il tipo di risponditore e rintracciare il suo bambino (sottoview, controller vista bambino).

Problemi correlati