2011-06-23 15 views
6

Desidero ottenere un riferimento puntatore a UIKeyboard *keyboard sulla tastiera sullo schermo in modo che sia possibile aggiungere una sottoview trasparente ad esso, coprendolo completamente, per ottenere l'effetto di disabling the UIKeyboard without hiding it.iOS: come accedere a `UIKeyboard`?

Nel fare questo, posso supporre che c'è uno solo UIKeyboard sullo schermo alla volta? Io, è un singleton? Dov'è il metodo [UIKeyboard sharedInstance]. Brownie punta se si implementa tale metodo tramite una categoria. O, ancora più punti brownie se mi convinci perché è una cattiva idea assumere solo una tastiera e darmi una soluzione migliore.

risposta

5

Che ne dici di utilizzare -[UIApplication beginIgnoringInteractionEvents]?

Inoltre, un altro trucco per ottenere la vista contenente la tastiera è di inizializzare una vista fittizio con CGRectZero e impostarlo come il inputAccessoryView del vostro UITextField o UITextView. Quindi, ottieni il suo superview. Tuttavia, tali shenanigans sono private/non documentate, ma ho sentito parlare di app che lo fanno e di essere accettato comunque. Voglio dire, in quale altro modo Instagram sarebbe in grado di rendere la loro tastiera interattiva dei commenti (congedo al passaggio del mouse) come la tastiera dei messaggi?

+0

Come si può usare 'beginIgnoringInteractionEvents'? –

7

Prova questo:

// my func 
- (void) findKeyboard { 

    // Locate non-UIWindow. 
    UIWindow *keyboardWindow = nil; 
    for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { 
     if (![[testWindow class] isEqual:[UIWindow class]]) { 
      keyboardWindow = testWindow; 
      break; 
     } 
    } 

    // Locate UIKeyboard. 
    UIView *foundKeyboard = nil; 
    for (UIView *possibleKeyboard in [keyboardWindow subviews]) { 

     // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView. 
     if ([[possibleKeyboard description] hasPrefix:@"<UIPeripheralHostView"]) { 
      possibleKeyboard = [[possibleKeyboard subviews] objectAtIndex:0]; 
     }                     

     if ([[possibleKeyboard description] hasPrefix:@"<UIKeyboard"]) { 
      foundKeyboard = possibleKeyboard; 
      break; 
     } 
    } 
} 
+1

Ciao, Non funziona su iOS7. –

+0

Per generica di codifica si prega di sostituire se la condizione del ciclo for per if ([[descrizione possibleKeyboard] hasPrefix: @ "

1

essere consapevoli, Apple ha messo in chiaro che le applicazioni che modificano vista gerarchie private senza l'approvazione esplicita anticipo verrà rifiutato. Dai un'occhiata ai forum degli sviluppatori Apple per l'esperienza di vari sviluppatori sul problema.

Se si sta solo cercando di disabilitare la tastiera (impedendo di ricevere tocchi), si potrebbe provare ad aggiungere un UIView trasparente che è la dimensione completa dello schermo per l'orientamento corrente. Se lo aggiungi come sottoview alla finestra principale, lo potrebbe funzionare. Apple non ha reso pubblico alcun metodo di disattivazione della tastiera di cui sono a conoscenza: potresti voler utilizzare uno dei tuoi problemi di supporto con Apple, forse ti lasceranno entrare nella soluzione.

+0

OK. C'è un modo per disabilitare la tastiera senza nasconderlo? – ma11hew28

+0

Stai cercando di impedire che la tastiera venga visualizzata quando un utente tocca un campo di testo? – RyanR

+0

No, voglio disabilitarlo durante un'animazione. La funzione Blocco passcode di Apple esegue questa operazione quando si imposta un passcode. – ma11hew28

4

Ho trovato che la risposta di developerdoug non funzionava su iOS 7, ma modificando leggermente le cose sono riuscito a ottenere l'accesso a ciò di cui avevo bisogno. Ecco il codice che ho usato:

-(UIView*)findKeyboard 
{ 
    UIView *keyboard = nil; 

    for (UIWindow* window in [UIApplication sharedApplication].windows) 
    { 
     for (UIView *possibleKeyboard in window.subviews) 
     { 
      if ([[possibleKeyboard description] hasPrefix:@"<UIPeripheralHostView"]) 
      { 
       keyboard = possibleKeyboard; 
       break; 
      } 
     } 
    } 

    return keyboard; 
} 

Da quello che ho potuto capire, in iOS 7 la tastiera è composta da un UIPeripheralHostView contenenti due subviews: un UIKBInputBackdropView (che fornisce l'effetto di sfocatura su qualunque è sotto la tastiera) e una UIKeyboardAutomatic (che fornisce i tasti dei caratteri). Manipolare il UIPeripheralHostView sembra essere equivalente a manipolare l'intera tastiera.

Discaimer: Non ho idea se Apple accetterà un'app che utilizza questa tecnica, né se continuerà a funzionare nei futuri SDK.

+0

Grazie. Ma vorrei usare un controllo leggermente diverso per la tastiera: '' 'Class keyboardClass = NSClassFromString (@" UIPeripheralHostView "); if ([possibleKeyboard isKindOfClass: keyboardClass]) '' '. Invece di fare affidamento su una descrizione di stringa. Dovrebbe anche essere un po 'più performante. –

+0

ottimo suggerimento. funziona bene in 7.1. Come posso trovare la tastiera quando è fuori dallo schermo? o è distrutto e non esiste? – mihai

+0

Non funziona su iOS 10. –

1

Per un app Attualmente sto sviluppando Sto usando un metodo davvero semplice e veloce:

Aggiungere questo nel file di intestazione:

// Add in interface 
UIWindow * _window; 

// Add as property 
@property (strong, nonatomic) IBOutlet UIView * _keyboard; 

Quindi aggiungere questo codice nella parte inferiore della funzione keyboardWillShow :

-(void) keyboardWillShow: (NSNotification *) notification { 

    .... // other keyboard will show code // 

    _window = [UIApplication sharedApplication].windows.lastObject; 

    [NSTimer scheduledTimerWithTimeInterval:0.05 
            target:self 
            selector:@selector(allocateKeyboard) 
            userInfo:nil 
            repeats:NO]; 
} 

Questo codice cerca quando la tastiera viene sollevata e quindi alloca la finestra corrente.Ho quindi aggiunto un timer per allocare la tastiera in quanto vi erano alcuni problemi quando allocati immediatamente.

- (void)allocateKeyboard { 

    if (!_keyboard) { 
     if (_window.subviews.count) { 

      // The keyboard is always the 0th subview 
      _keyboard = _window.subviews[0]; 
     }   
    } 
} 

A questo punto è stata assegnata la tastiera che consente di "accedere" direttamente alla tastiera come richiesto dalla domanda.

Spero che questo aiuti

0

sotto iOS 8 sembra dovrete saltare giù per la catena più rispetto al passato. I seguenti lavori per me per ottenere la tastiera, anche se con tastiere personalizzate disponibili e tali non farei affidamento su questo funziona a meno che non stai correndo in un ambiente controllato.

- (UIView *)findKeyboard { 
    for (UIWindow* window in [UIApplication sharedApplication].windows) { 
     UIView *inputSetContainer = [self viewWithPrefix:@"<UIInputSetContainerView" inView:window]; 
     if (inputSetContainer) { 
      UIView *inputSetHost = [self viewWithPrefix:@"<UIInputSetHostView" inView:inputSetContainer]; 
      if (inputSetHost) { 
       UIView *kbinputbackdrop = [self viewWithPrefix:@"<_UIKBCompatInput" inView:inputSetHost]; 
       if (kbinputbackdrop) { 
        UIView *theKeyboard = [self viewWithPrefix:@"<UIKeyboard" inView:kbinputbackdrop]; 
        return theKeyboard; 
       } 
      } 
     } 
    } 

    return nil; 
} 


- (UIView *)viewWithPrefix:(NSString *)prefix inView:(UIView *)view { 
    for (UIView *subview in view.subviews) { 
     if ([[subview description] hasPrefix:prefix]) { 
      return subview; 
     } 
    } 

    return nil; 
} 
+0

impedirà l'approvazione di App Store? – matteok

+0

@matteok Questo da solo - non credo. Qualunque cosa tu abbia intenzione di fare con la tastiera, probabilmente lo farebbe. L'ho usato per motivi aziendali specifici. – alparsons

+0

Cosa succede se si applica una trasformazione alla finestra della tastiera durante una transizione? – matteok

Problemi correlati