iphone - searchcontroller - UISearchDisplayController sin resultados tableView?
uisearchbar swift 4 (10)
¿Has probado esto?
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_lookup:) object:nil];
[self performSelector:@selector(_lookup:) withObject:txt afterDelay:0.20];
De esta forma, si el usuario escribe otro carácter en 1 / 5seg, solo realiza una llamada web.
Por lo general, un UISearchDisplayController, cuando está activado, atenúa tableView y enfoca la barra de búsqueda. Tan pronto como ingresa texto en la barra de búsqueda, crea una vista de resultados de búsqueda que se muestra entre la barra de búsqueda y el teclado. Se llama al delegado de searchDisplayController cuando este segundo UITableView se carga / muestra / oculta / descarga. Por lo general, muestra resultados de búsqueda en vivo o entradas de autocompletado mientras se escribe.
En mi aplicación, deseo buscar un servicio web y no quiero llamar al servicio web por cada letra que ingrese el usuario. Por lo tanto, quiero desactivar por completo searchResultsTableView y mantener la superposición negra atenuada mientras ingresa texto. Luego activaría la búsqueda (con una pantalla de carga) una vez que presione el botón de búsqueda.
Simplemente devolviendo cero filas para searchResultsTableView no se ve bien, ya que muestra un searchResultsTableView vacío con un mensaje "sin resultados". Traté de ocultar la tabla cuando aparece ( searchDisplayController:didLoadSearchResultsTableView:
que funciona, pero la superposición oscurecida oscurecida también está oculta para que el tableView subyacente esté completamente visible de nuevo.
¿Alguna idea además de recrear la funcionalidad UISearchDisplayController desde cero?
¿Qué tal simplemente hacerlo tan simple como esto?
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
self.searchDisplayController.searchResultsTableView.hidden=YES;
return YES;
}
Funciona bien para mí ...
Basado en el código de usuario182820 a continuación es mi versión. Oculto la vista de tabla de UISearchDisplayController. Cuando se ingresa un personaje en el cuadro de búsqueda, coloco una ''vista atenuada'' para que parezca que la ''vista atenuada'' de UISearchDisplayController nunca desapareció y luego la elimino cuando finaliza la búsqueda. Si ingresa algunos caracteres y presiona cancelar, la vista de tabla se vuelve completamente blanca y no sé cómo evitar esto.
- (void)viewDidLoad {
...
tableViewMask=[UIView new];
tableViewMask.backgroundColor = [UIColor blackColor];
tableViewMask.alpha = 0.8;
}
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller{
tableViewMask.frame=CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y+controller.searchBar.frame.size.height, self.tableView.frame.size.width, self.tableView.frame.size.height-controller.searchBar.frame.size.height);
controller.searchResultsTableView.hidden=YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller{
[tableViewMask removeFromSuperview];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
if (searchString.length==0)
[tableViewMask removeFromSuperview];
else
[self.tableView addSubview:tableViewMask];
[searchText autorelease];
searchText=[searchString retain];
return NO;
}
Creo que encontré una mejor implementación para este problema. Todas las respuestas anteriores muestran correctamente una vista atenuada idéntica a la apariencia de UITableView antes de una búsqueda, pero cada solución carece de la funcionalidad para tocar el área y cancelar la búsqueda.
Por esa razón, creo que este código funciona mejor.
En primer lugar, cree un BOOL como searchButtonTapped para indicar si se hizo clic en el botón de búsqueda. Por defecto es NO.
Entonces:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
if (!searchButtonTapped) {
// To prevent results from being shown and to show an identical look to how the tableview looks before a search
[controller.searchResultsTableView setBackgroundColor:[UIColor clearColor]];
[controller.searchResultsTableView setRowHeight:160];
self.searchDisplayController.searchResultsTableView.scrollEnabled = NO;
} else {
// Restore original settings
[controller.searchResultsTableView setBackgroundColor:[UIColor whiteColor]];
[controller.searchResultsTableView setRowHeight:44];
self.searchDisplayController.searchResultsTableView.scrollEnabled = YES;
}
return YES;
}
Esto debería ser claro ahora en base a las otras respuestas. Asegúrese de restaurar también la configuración original cuando el usuario toque el botón Buscar.
Además, en el método cellForIndexPath, agregue:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.contentView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.8];
Para crear la misma vista atenuada que se muestra antes de ingresar el texto. Asegúrese de aplicar estas propiedades a la celda correcta, es decir, verificar qué UITableView está activo y que el usuario no ha tocado el botón Buscar.
Entonces, de manera crucial, en didSelectRowAtIndexPath:
if (tableView == self.searchDisplayController.searchResultsTableView) {
if (searchButtonTapped) {
// Code for when the user select a row after actually having performed a search
{
else
[self.searchDisplayController setActive:NO animated:YES];
Ahora el usuario puede tocar el área atenuada, lo que no dará como resultado una selección visible de una UITableViewCell, sino que cancela la búsqueda.
Creo que es mejor, ya que hay un error con la "mejor respuesta": el separador y el "Sin resultados" se mostrarán al desplazarse por la tabla de fondo negro.
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
controller.searchResultsTableView.backgroundColor = [UIColor blackColor];
controller.searchResultsTableView.alpha = 0.8;
controller.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
for(UIView *subview in tableView.subviews) {
if([subview isKindOfClass:UILabel.class]) {
subview.hidden = YES;
}
}
return NO;
}
- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
self.searchDisplayController.searchResultsTableView.backgroundColor = [UIColor whiteColor];
self.searchDisplayController.searchResultsTableView.alpha = 1;
self.searchDisplayController.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
for(UIView *subview in tableView.subviews) {
if([subview isKindOfClass:UILabel.class]) {
subview.hidden = NO;
}
}
// search results and reload data ....
}
Nada de lo anterior pareció funcionar bien al final, así que se me ocurrió lo siguiente (debes llamar a removeTableHeader cuando estés listo para mostrar tus resultados):
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
[self setTableHeader];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
[self setTableHeader];
}
- (void)setTableHeader {
UIView *headerView = [[UIView alloc] initWithFrame:self.searchDisplayController.searchResultsTableView.frame];
headerView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
[self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor clearColor]];
[self.searchDisplayController.searchResultsTableView setScrollEnabled:NO];
[self.searchDisplayController.searchResultsTableView setTableHeaderView:headerView];
[headerView release];
}
- (void)removeTableHeader {
[self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor whiteColor]];
[self.searchDisplayController.searchResultsTableView setScrollEnabled:YES];
[self.searchDisplayController.searchResultsTableView setTableHeaderView:nil];
}
Obviamente, hace que la tabla sea transparente, agrega un encabezado de tabla negra / translúcida con el mismo tamaño que la tabla y deshabilita el desplazamiento en la tabla para que no pueda pasar por encima o pasar el encabezado. Como beneficio adicional, puede agregar algo a la vista de encabezado (''por favor espere ...'' o un indicador de actividad).
Todas las respuestas existentes son excesivamente complicadas. Puede escapar ocultando la vista de tabla de resultados inmediatamente.
-(void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
tableView.hidden = YES;
}
Tuve el mismo problema que tú, lo manejé a ) estableciendo el alfa de searchResultsTableView en 0 al comenzar la búsqueda, y luego b) agregando / quitando el overlayView a la vista del viewController. Funciona como un encanto para mí.
@interface MyViewController()
//...
@property(nonatomic, retain) UIView *overlayView;
//...
@end
@implementation MyViewController
@synthesize overlayView = _overlayView;
//...
- (void)viewDidLoad
{
//...
//define your overlayView
_overlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 480)];
_overlayView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.8];
}
//hide the searchResultsTableView
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
self.searchDisplayController.searchResultsTableView.alpha = 0.0f;
}
//when ending the search, hide the overlayView
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[_overlayView removeFromSuperview];
}
//depending on what the user has inputed, add or remove the overlayView to the view of the current viewController
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
if ([searchString length]>0)
{
[self.view addSubview:_overlayView];
}
else
{
[_overlayView removeFromSuperview];
}
return NO;
}
@end
aquí hay un pequeño truco que acabo de descubrir y también tienes que devolver 0 resultados mientras editas searchstring
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
savedSearchTerm = searchString;
[controller.searchResultsTableView setBackgroundColor:[UIColor colorWithWhite:0.0 alpha:0.8]];
[controller.searchResultsTableView setRowHeight:800];
[controller.searchResultsTableView setScrollEnabled:NO];
return NO;
}
- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
// undo the changes above to prevent artefacts reported below by mclin
}
Creo que sabrá qué hacer a continuación
debería ser suficiente implementar el siguiente método en su UISearchDisplayDelegate (que generalmente es su subclase UITableViewController personalizada)
- (BOOL) searchDisplayController: (UISearchDisplayController *) controller shouldReloadTableForSearchString: (NSString *) searchString
{
[self startMyCustomWebserviceSearchAsBackgroundProcessForString: searchString]; //starts new NSThread
return NO;
}
¿Has probado esto?