11

Ich habe eine Nicht-Tabellenansicht mit einer Suchleiste darin, und während es perfekt funktioniert, verbirgt der Search Display Controller die Tabellenansicht und überlagert eine dunkle abgeblendete Ansicht, wenn eine leere Zeichenfolge in der Suchleiste ist. Ich möchte, dass eine vorgeladene Datei angezeigt wird, wenn sich die leere Zeichenfolge in der Suchleiste befindet, anstatt die Tabellenansicht zu verbergen und die dunkel abgeblendete Ansicht unterhalb der Suchleiste zu überlagern. Genauso wie die Google Suchleiste in Safari für iOS funktioniert.Vorinstallierte Suchergebnisse anzeigen?

Ich fand eine ähnliche Frage auf stackoverflow zuvor gestellt: UISearchDisplayController - how to preload searchResultTableView, ich konnte es nicht wirklich zum Laufen bringen.

Ich habe kein Problem, die vorgeladenen Daten und die aktuellen Daten zu erhalten, aber ich bin mir nicht sicher, wie zu verhindern, dass der Displaycontroller die searchResultsTableView entfernen.

Vielen Dank im Voraus.

Antwort

13

Ich habe endlich einen Weg gefunden, dies zu tun.

Ich fand heraus, dass die searchDisplayController einfach die searchResultsTableView aus dem Superview entfernt, so habe ich nur noch die Tabellen-Ansicht zurück in die Superview, wenn die Anzeigesteuerung die Tabellen-Ansicht zu verbergen versucht: Ich

- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView 
{ 
    // add the tableview back in 
    [self.view addSubview:self.searchDisplayController.searchResultsTableView]; 
} 

und dann müssen auch die searchbar die Tableview zum ersten Mal zeigen geklickt wird, also tat ich:

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller 
{ 
    // after the data has been preloaded 
    self.searchResults = self.allItems; 
    [self.searchDisplayController.searchResultsTableView reloadData]; 
} 

- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller 
{ 
    [self.view addSubview:self.searchDisplayController.searchResultsTableView]; 
} 

Für mich ‚AllItems‘ ist, wo ich alle durchsuchbaren Elemente und ‚search‘ gespeichert wird, in dem die gefilterten Elemente (nach die Suche) ist gelagert. Und natürlich müssten Sie die Elemente vorab laden (z. B. Suchverlauf), bevor Sie die Daten erneut laden.

Ich weiß nicht, ob das ein schöner Weg ist oder nicht, um es in Bezug auf die Leistung und was nicht zu tun, aber es funktionierte perfekt für mich, und ich hoffe, dass dies auch für andere Menschen nützlich sein könnte. Bitte kommentieren Sie, wenn es einen besseren Weg gibt, dies zu tun.

+0

great stuff, vielen Dank für dieses – NSTJ

+0

versucht, dies jetzt Tage, um herauszufinden! Danke für die Lösung! –

+1

Nach dem Testen dieser Implementierung möchte ich nun herausfinden, wie der Suchergebniscontainer nicht flackern kann, wenn er der Ansicht hinzugefügt wird. Da es über die 'searchDisplayControllerDidBeginSearch:' Methode hinzugefügt wird, können Sie den dunklen Hintergrund für einen Bruchteil einer Sekunde sehen, bevor die 'searchResultsTableView' angezeigt wird. Irgendwelche Gedanken darüber, wie man das umgehen kann? Ich habe versucht, die Codezeile in der 'searchDisplayControllerDidBeginSearch' in die' searchDisplayControllerWillBeginSearch'-Methode zu verschieben, aber das bringt den dunklen Hintergrund vor die 'searchResultsTableView' –

1

Wenn Sie mit der Suche beginnen, wird diese Methode aufgerufen. Fügen Sie die searchResultsTableView hinzu und blenden Sie sie ein. Es würde dann Ihre bereits vorgeladenen Daten anzeigen. Ich muss Ihre Daten vorgeladen haben, damit dies funktioniert.

- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller 
{ 
    CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height); 
    self.searchDisplayController.searchResultsTableView.frame = testFrame; 
    [self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView]; 

// [self.view addSubview:self.searchDisplayController.searchResultsTableView]; 
    controller.searchResultsTableView.hidden = NO; 
} 

-(void) searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView 
{ 
    CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height); 
    self.searchDisplayController.searchResultsTableView.frame = testFrame; 
    [self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView]; 

    // [self.view addSubview:self.searchDisplayController.searchResultsTableView]; 
    controller.searchResultsTableView.hidden = NO; 
} 


-(void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller 
{ 
    controller.searchResultsTableView.hidden = YES; 
} 
4

Nach Stunden und Stunden, die ich eine Lösung endlich herausgefunden, dass in iOS funktioniert 7

einfach die folgenden zwei Methoden in Ihrem UISearchDisplayDelegate implementieren

-(void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView { 

    // We need to prevent the resultsTable from hiding if the search is still active 
    if (self.searchDisplayController.active == YES) { 
     tableView.hidden = NO; 
    } 
} 

Wenn die Suche beginnt, wird die searchResultsTableView ist wird automatisch ausgeblendet, so dass wir es wieder einblenden müssen.

+0

Das hat bei iOS7 nicht funktioniert. Stattdessen habe ich überprüft, ob (v.alpha <1), scheint wie der "nachhaltigste" Hack. –

+0

Es hat für mich funktioniert, schön! –

4

Ich fand eine viel bessere Lösung für dieses Problem, und es scheint perfekt auf iOS 6 und 7 zu funktionieren. Während es immer noch ein Hack ist, ist es ein viel sauberer und zukunftssicherer Hack als die oben genannten. Die anderen Lösungen funktionieren nicht konsistent und verhindern, dass einige UISearchDisplayDelegate-Methoden jemals ausgelöst werden! Außerdem hatte ich komplexe Einfügeprobleme, die ich mit den oben genannten Methoden nicht lösen konnte. Das Hauptproblem bei den anderen Lösungen besteht darin, dass sie die Interna des UISearchDisplayControllers ernsthaft durcheinander bringen.Meine Lösung basiert auf der Beobachtung, dass UISearchDisplayContoller ein UISearchbarDelegate ist und dass die automatische Anzeige der Ergebnistabelle & durch Simulieren eines Tastendrucks im Suchfeld ausgelöst werden kann! Also:

- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller 
{ 
    if ([controller respondsToSelector: @selector(searchBar:textDidChange:)]) 
     [(id<UISearchBarDelegate>)controller searchBar: controller.searchBar textDidChange: @" "]; 
} 

Dieser Code ist zukunftssicher gegen Absturz durch Überprüfung an die UISearchbarDelegate Methode reagiert und sendet Raum @“", um die UISearchDisplayController zu verleiten Benutzer denken einen Brief getippt hat.

Nun, wenn der Benutzer etwas eingibt und dann löscht, wird die Tabelle wieder abgedunkelt. Die anderen Lösungen versuchen, dies zu umgehen, indem sie etwas in der searchDisplayController: didHideSearchResultsTableView: -Methode tun. Aber das ergibt für mich keinen Sinn, denn wenn Sie die Suche abbrechen, muss Ihre Ergebnistabelle wirklich ausgeblendet werden. In diesem Fall müssen Sie möglicherweise Code ausführen. Meine Lösung für diesen Teil ist (beachten Sie wahrscheinlich eine Methode umgestellt Kategorie nutzen könnte, um es überall funktioniert, wenn in Ihrem Projekt erforderlich) Unterklasse:

// 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 

Dieser Code funktioniert, indem die textDidChange Delegatmethode Abfangen und Ändern von null oder leere Strings in die Space-Zeichenfolge @ "" verhindern das normale Ausblenden/Dimmen, das in einer leeren Suchleiste auftritt. Wenn Sie dieses zweite Bit verwenden, können Sie das erste Bit so ändern, dass anstelle von @ "" eine Null übergeben wird, da dieses zweite Bit die erforderliche Umwandlung in @ "" für Sie übernimmt.

In meinem eigenen Projekt, ich brauchte den Fall zu behandeln, dass der Benutzer einen Raum nicht geben, so dass anstelle von @“" I oben eine definierte Token verwendet:

// arbitrary token used internally 
#define SEARCH_PRELOAD_CONDITIONAL @"_#preresults#_" 

Und es dann intern handhaben, indem sie die Umwandlung zurück zu Null String:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString 
{ 
    if ([searchString isEqualToString: SEARCH_PRELOAD_CONDITIONAL]) 
     searchString = nil; 
} 

Viel Spaß! :)

2

Dies funktioniert in iOS 8:

- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView 
{ 
    self.searchDisplayController.searchResultsTableView.hidden = NO; 
} 

- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller 
{ 
    self.searchDisplayController.searchResultsTableView.hidden = NO; 
    [self.searchDisplayController.searchResultsTableView.superview.superview bringSubviewToFront:self.searchDisplayController.searchResultsTableView.superview]; 

    CGRect frame = self.searchDisplayController.searchResultsTableView.frame; 
    self.searchDisplayController.searchResultsTableView.frame = CGRectMake(frame.origin.x, 64, frame.size.width, frame.size.height); 
} 
0

iOS 9-Code arbeiten.

- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller { 
    // Bring the search table view to the view's front 
    self.searchDisplayController.searchResultsTableView.hidden = NO; 
    [self.searchDisplayController.searchResultsTableView.superview bringSubviewToFront:self.searchDisplayController.searchResultsTableView]; 
} 

- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView { 
    // We need to prevent the resultsTable from hiding if the search is still active 
    if (self.searchDisplayController.active == YES) { 
     tableView.hidden = NO; 
    } 
} 
0

Swift 2.0+ Version

func searchDisplayControllerDidBeginSearch(controller: UISearchDisplayController) { 
    controller.searchResultsTableView.hidden = false 
    controller.searchResultsTableView.superview!.bringSubviewToFront(controller.searchResultsTableView) 
} 

func searchDisplayController(controller: UISearchDisplayController, didHideSearchResultsTableView tableView: UITableView) { 
    if ((searchDisplayController?.active) != nil) { 
     tableView.hidden = false 
    } 
}