Ho trovato una molto migliore soluzione a questo problema, e sembra funzionare perfettamente su iOS 6 e 7. Anche se è ancora un hack, è un trucco molto più pulito e futuro di quanto sopra. Le altre soluzioni non funzionano in modo coerente e impediscono l'attivazione di alcuni metodi di UISearchDisplayDelegate! Inoltre ho avuto problemi di insorgenza complessi che non ho potuto risolvere con i metodi di cui sopra. Il problema principale con le altre soluzioni è che confondono seriamente i componenti interni di UISearchDisplayController.La mia soluzione si basa sull'osservazione che UISearchDisplayContoller è un UISearchbarDelegate e che la visualizzazione automatica della tabella dei risultati & può essere attivata simulando una pressione di tasto nel campo di ricerca! Quindi:
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
if ([controller respondsToSelector: @selector(searchBar:textDidChange:)])
[(id<UISearchBarDelegate>)controller searchBar: controller.searchBar textDidChange: @" "];
}
Questo codice è a prova di futuro contro schiantarsi controllando risponde al metodo UISearchbarDelegate, e invia spazio @"" per ingannare l'UISearchDisplayController a pensare utente ha digitato una lettera.
Ora se l'utente digita qualcosa e quindi lo cancella, la tabella si oscurerà di nuovo. Le altre soluzioni cercano di aggirare questo facendo qualcosa nel searchDisplayController: didHideSearchResultsTableView: method. Ma questo non ha senso per me, come sicuramente quando annulli la ricerca occorrerà nascondere la tabella dei risultati e potrebbe essere necessario eseguire il codice in questo caso. La mia soluzione per questa parte è quello di creare una sottoclasse (si nota probabilmente potrebbe usare un metodo Swizzled categoria per farlo funzionare ovunque, se necessario, nel progetto):
// privately declare protocol to suppress compiler warning
@interface UISearchDisplayController (Super) <UISearchBarDelegate>
@end
// subclass to change behavior
@interface GMSearchDisplayController : UISearchDisplayController
@end
@implementation GMSearchDisplayController
- (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchString
{
if (searchString.length == 0)
searchString = @" ";
if ([super respondsToSelector: @selector(searchBar:textDidChange:)])
[super searchBar: searchBar textDidChange: searchString];
}
@end
Questo codice funziona intercettando il metodo delegato textDidChange e cambiare nulla o stringhe vuote nella stringa di spazio @ "" che impediscono il normale nascondiglio/oscuramento che si verifica su una barra di ricerca vuota. Se si utilizza questo secondo bit di codice, è possibile modificare il primo bit per passare un nil anziché @ "" poiché questo secondo bit eseguirà la conversione necessaria per @ "".
Nel mio progetto, ho bisogno per gestire il caso che l'utente non digitare uno spazio, così invece di @"" di cui sopra ho usato un gettone definito:
// arbitrary token used internally
#define SEARCH_PRELOAD_CONDITIONAL @"_#preresults#_"
E poi gestirlo internamente convertendolo torna alla stringa zero:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
if ([searchString isEqualToString: SEARCH_PRELOAD_CONDITIONAL])
searchString = nil;
}
Divertiti! :)
grandi cose, grazie per questo – NSTJ
cercato di capire questo fuori da giorni ormai! Grazie per la soluzione! –
Dopo aver testato questa implementazione, ora voglio capire come ottenere che il contenitore dei risultati di ricerca non sfarfallio quando viene aggiunto alla vista. Poiché viene aggiunto tramite il metodo 'searchDisplayControllerDidBeginSearch:', è possibile vedere lo sfondo scuro per una frazione di secondo prima che venga visualizzato 'searchResultsTableView'. Qualche idea su come aggirare questo? Ho provato a spostare la riga di codice in 'searchDisplayControllerDidBeginSearch' al metodo' searchDisplayControllerWillBeginSearch ', ma questo fa sì che lo sfondo scuro venga posto di fronte a 'searchResultsTableView' –