tutorial example custom bar and iphone search uitableview

iphone - example - uisearchbar swift 4



¿Cambiando el tamaño de UISearchBar TextField? (17)

¡Funciona bien!

[searchBar setContentInset:UIEdgeInsetsMake(5, 0, 5, 35)];

Tengo una UITableView con un índice en el lateral; Quiero agregarle un UISearchBar, pero el índice se superpone con la "x" para borrar la búsqueda. Me di cuenta que en la aplicación Contactos, el campo de texto dentro de UISearchBar se redimensiona para acomodar esto, pero no puedo encontrar la manera de hacerlo en mi propia aplicación.

He intentado lo siguiente en mi viewDidLoad, pero parece que no funciona.

UITextField * textField = (UITextField *)[[self.search subviews] objectAtIndex:0]; CGRect r = textField.frame; [textField setFrame:CGRectMake(r.origin.x, r.origin.y, r.size.height, r.size.width-30)];

¿Algunas ideas?


¿Por qué no simplemente hacer que el UISearchBar real sea más pequeño horizontalmente y coloque un UINavigationBar (vacío) a la derecha del mismo? Ellos renderizarán el mismo fondo exacto.

Mejor que piratear las partes internas de los objetos de Apple que podrían cambiar.

Además, al animar el ancho de UISearchBar, notará que el campo de texto interno no está animado junto con él. Puedes arreglar esto llamando a "layoutSubviews" de UISearchBar dentro de tu bloque de animación después de cambiar su fotograma. (ahí es donde determina el tamaño del campo de texto interno)


A partir de iOS 6, la solución de barra de navegación no me funcionó debido a miradas ligeramente diferentes ahora entre UISearchBar y UINavigationBar. Entonces, cambié a algo similar al enfoque de Padraig al subclasificar el UISearchBar.

@interface SearchBarWithPad : UISearchBar @end @implementation SearchBarWithPad - (void) layoutSubviews { [super layoutSubviews]; NSInteger pad = 50; for (UIView *view in self.subviews) { if ([view isKindOfClass: [UITextField class]]) view.frame = CGRectMake (view.frame.origin.x, view.frame.origin.y, view.frame.size.width - pad, view.frame.size.height); } } @end

Editar: Ah, no lo he intentado, pero creo que es posible que pueda establecer clipToBounds = YES en la barra de navegación para desactivar su nueva sombra, creando así una apariencia uniforme entre los dos controles.


Como Padraig señaló, todo lo que tienes que hacer es crear una subclase de la barra de búsqueda. Cree su subclase UISearchBar y agregue el siguiente código en el método layoutSubviews :

- (void)layoutSubviews { UITextField *searchField; for(int i = 0; i < [self.subviews count]; i++) { if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]]) { searchField = [self.subviews objectAtIndex:i]; } } if(!(searchField == nil)) { searchField.frame = CGRectMake(4, 5, 285, 30); } }

Esto recorre todas las subvistas y las compara con el tipo UITextField. De esa manera, si alguna vez se mueve en su alineación de subvistas, esto aún lo agarrará. Encontré 285 lo suficientemente ancho como para no superponerme con el índice de mi tableView.


El campo de texto utilizado en UISearchBar es una subclase de UITextField llamada UISearchBarTextField.

AFAIK, no hay forma de redimensionar un UISearchBarTextField usando la API pública, y la API privada tampoco revela mucho.

Tal vez pueda echar un vistazo a las subvistas de UISearchBarTextField, si tiene alguna.

ACTUALIZACIÓN: No es así.

ACTUALIZACIÓN 2: Creo que debería echar un vistazo a la propiedad RightView de UITextField. El siguiente código, aunque no funciona, parece ser un buen punto de partida:

UIView *emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)]; [textField setRightView:emptyView]; [textField setRightViewMode:UITextFieldViewModeAlways]; [emptyView release];


Estoy usando ViewDeck y quiero mostrar una UISearchbar dentro del leftController .

Ahora el problema es si abro el lado izquierdo que contiene la navegación, el bit derecho se superpone a mi campo de búsqueda.

Me deshice de esto al escribir UISearchBar , el campo de texto siempre tendrá el mismo ancho, pero en un caso está la superposición de ViewDeck y en el otro caso, oculto ViewDeck-bit y luego el botón cancelar ocupará el espacio:

Subclassing UISearchBar

#import "ViewDeckSearchBar.h" #define kViewDeckPadding 55 @interface ViewDeckSearchBar() @property (readonly) UITextField *textField; @end @implementation ViewDeckSearchBar static CGRect initialTextFieldFrame; - (void) layoutSubviews { [super layoutSubviews]; // Store the initial frame for the the text field static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ initialTextFieldFrame = self.textField.frame; }); [self updateTextFieldFrame]; } -(void)updateTextFieldFrame{ int width = initialTextFieldFrame.size.width - (kViewDeckPadding + 6); CGRect newFrame = CGRectMake (self.textField.frame.origin.x, self.textField.frame.origin.y, width, self.textField.frame.size.height); self.textField.frame = newFrame; } -(UITextField *)textField{ for (UIView *view in self.subviews) { if ([view isKindOfClass: [UITextField class]]){ return (UITextField *)view; } } return nil; } @end

Clase ViewController

En mi clase de Navegación necesito sobrescribir estos dos métodos UISearchbarDelegate para ir a pantalla completa con los resultados de búsqueda:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{ [self.viewDeckController setLeftSize:0]; // I am also using scopes, which works fine (they fade out when not searching) self.searchBar.scopeButtonTitles = @[@"Food", @"Beverages", @"Misc"]; } -(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{ self.viewDeckController.leftSize = 55; }

Resultado

ViewDeck que se muestra a la derecha:

a http://i5.minus.com/jA34MnXVqPZez.png

Buscar en pantalla completa (el botón y los botones de alcance están animados).

a http://i2.minus.com/jjKEgXLur1kH6.png


La clave es usar la "Barra de búsqueda y el Controlador de visualización de búsqueda" y no la "Barra de búsqueda" cuando se utiliza el Constructor de interfaz.


Lo que se me ocurrió no es mucho mejor. Básicamente, hago una vista vacía con el marco que quiero usar para la barra de búsqueda. Luego creo una UIToolbar para ir detrás de la barra de búsqueda. Asegúrese de establecer su marco en el mismo marco que el UIView, excepto que el valor Y debe ser -1; de lo contrario, obtendrás dos bordes dibujados en la parte superior. Luego crea tu UISearchBar, pero establece el ancho del marco en 30 (o lo que tenga sentido para tu aplicación) menos que UIView. Agréguelos como subvistas y configure su UIView como tableHeaderView.


Lo siento por Necroposting, pero encontré otra forma de hacer un pequeño espacio a la derecha del campo de texto. Estaba teniendo el problema, que tenía una tabla indexada con una barra de búsqueda como primera fila. Ahora el índice y la barra de búsqueda (realizados en IB, por cierto) se superponen. Probó casi todo sin éxito. Parece que las propiedades de ancho y alto del campo de texto no responden ... Así que se me ocurrió esto:

searchBar.showsCancelButton = YES; UIView *cButton = [searchBar.subviews objectAtIndex:2]; cButton.hidden = YES;

Todavía no puedo ajustar el tamaño del espacio, pero esto lo hace por ahora ... aunque ... solución bastante extraña ...


Ok, he encontrado una solución.

  1. Crear una subclase de UISearchBar
  2. Incluye este código en el método drawRect:

    UITextView * textField = [self.subviews objectAtIndex:0]; textField.frame = CGRectMake(5, 6, (310 - kRightSideMargin), 31); [super drawRect:rect];

Nota: kRightSideMargin es una constante que establecí en mi archivo de encabezado; Lo tengo configurado en 25.

Gracias por las sugerencias de todos los demás.


Otro enfoque (aunque tedioso) sería cambiar el tamaño de la barra de búsqueda y llenar el "espacio" con una barra de navegación. Funciona para mi.


Parece como si Apple cambiara el tamaño de la vista (tenga en cuenta que el índice está animado a la derecha, fuera de la pantalla), por lo que es más grande que la pantalla.

Me imagino que tendrías que implementar el método searchBarTextDidBeginEditing: de UISearchBarDelegate para activar esto en el punto apropiado. Esto, sin embargo, se siente un poco hacky, tal vez hay una mejor manera de hacerlo.


Perdón por arrastrar todo esto de nuevo.

Quería que el UISearchBar fuera más corto, y estoy usando un UISearchBarController, pero sin querer realmente el índice. Esto se debe a que tengo una superposición a la derecha:

Para hacer esto, falsifico un sectionIndex con un elemento en blanco, luego lo escondo. Así es como hago eso:

- (void)hideTableIndex { for (UIView *view in [tableView subviews]) { if ([view isKindOfClass:NSClassFromString(@"UITableViewIndex")]) { view.hidden = YES; } } } - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)aTableView { if (aTableView == self.searchDisplayController.searchResultsTableView) { return nil; } else { [self performSelector:@selector(hideTableIndex) withObject:nil afterDelay:0]; return [NSArray arrayWithObjects:@"", nil]; } } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { return 0; }

Esto acorta el UISearchBar y oculta el índice para que no se pueda tocar (una pequeña sección de otra manera pasaría a la izquierda de la superposición que cuando se toca desplazaría UITableView a la parte superior). Me gusta esto:

Lo mejor de todo es que cuando usas la búsqueda, sigues obteniendo la barra de ancho completo:


Seguí el consejo de Mike haciendo una UIView, luego puse una barra de navegación y una barra UISearch dentro de ella. El único problema es la primera vez que se muestra la barra de búsqueda, ¿su fondo es el mismo que el de una barra de navegación normalmente?

Curiosamente, si activo la búsqueda, ¿luego hago clic en cancelar el fondo de este ''fijo''?

Estoy usando SDK 3.0, así que eliminé el elemento UISearchBar creado cuando arrastré un UISearchDisplayController a mi NIB, luego realicé la vista como se describe arriba y la conecté con el propietario del archivo y la salida searchBar en el controlador de visualización de búsqueda.


Simplemente ponga una UIView y coloque la barra de búsqueda dentro de esa UIView. UIView debe ser del mismo tamaño que UISearchBar. esto funcionó para mí.


Todos han proporcionado formas de modificar la UI. He descubierto cómo obtener resultados idénticos. Debe proporcionar las siguientes dos implementaciones:

  1. Use UISearchDisplayController. Más importante aún, asegúrese de inicializarlo con:

- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController

Si no se establece un UISearchBar válido (o nulo pasante) impedirá el ajuste del UITextField para el índice.

  1. Debe devolver una matriz válida de títulos implementando:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;

Si devuelve nil, el índice no se mostrará y el UITextField no se ajustará correctamente.

He enviado un informe de error a Apple, sugiriendo que parece lógico que solo se requiera el n. ° 2, no el n. ° 1. No he encontrado nada en la Guía de Interfaz Humana (iPhone HIG) que requiera el uso del UISearchDisplayController.


es mucho más fácil que todas estas sugerencias. En el generador de interfaz, en lugar de poner la barra de búsqueda como el encabezado de su vista de tabla, puede poner una vista en su lugar. Luego, coloca una barra de navegación dentro de esta vista. Agarra el control de redimensionamiento izquierdo de la barra de navegación y tira de él hacia la derecha hasta que el NB tenga solo 25 píxeles de ancho. Limpie el Título en el NB (haga doble clic para seleccionarlo, luego elimínelo). Luego, agregue una barra de búsqueda en la misma vista. Mueva la manija de ajuste de tamaño derecha hacia la izquierda, ajústela de modo que colinde con la N B. Eso es todo.

También puede habilitar un botón de cancelación si lo desea y tampoco se superpondrá al índice (permanece dentro de la barra de búsqueda).

Aparentemente, una vista de tabla solo puede tener 1 subvista en su encabezado, por eso es necesario poner primero la vista, luego el NB y la barra de búsqueda dentro de ella.

ACTUALIZACIÓN: consulte Inicio de desarrollo de iPhone desde Apress, p. 241 de la edición SDK 3. Solo desactiva el índice mientras busca.

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { if (isSearching) { return nil; } return keys; }

También hablan de agregar una lupa a la parte superior del índice.

Gran libro por todos lados.