2010-08-20 9 views
8

Estoy escribiendo una aplicación SplitView para iPad. Dentro de DetailViewController, hay una pequeña vista que contiene un UITableView y un UISearchBar y su controlador. Esta vista no representa todo el espacio de la pantalla reservado para DetailViewController. En realidad, usa solo la mitad de eso. Hay un UIImageView en la otra mitad.UISearchDisplayController Without Dimming?

Y aquí es donde surgen problemas: cada vez que uso la barra de búsqueda, el controlador de pantalla (supongo) atenúa todo lo presente dentro de DetailViewController, incluida la vista de la imagen. Eso no es coherente con lo que alguien esperaría al ejecutar la aplicación. ¿Hay alguna manera de establecer el marco para ser atenuado? ¿O al menos desactivar el oscurecimiento para siempre?

Gracias de antemano.

Respuesta

11

Tiene razón en que es el UISearchDisplayController el que está administrando el efecto de "atenuación" que está viendo.

Lo que el UISearchDisplayController está haciendo es agregar un UIControl como una subvista a la vista de searchContentsController (una propiedad de UISearchDisplayController), que probablemente sea su controlador de vista de detalles. Este UIControl es solo una vista alfabética con fondo gris. Parece tener un controlador de eventos de retoque interno que finaliza la búsqueda cuando se toca.

Para restringir el efecto de atenuación a su subvista de la vista de detalles, debe hacer tres cosas. (Supongo que su controlador de detalle-vista se define a través de un xib. De lo contrario, estos pasos también se pueden hacer en código.)

1) agregue un nuevo UIViewController a su xib de controlador view-detail. Adjunte este nuevo controlador de vista a una IBOutlet de su detalle-vista-controlador. En mi ejemplo, yo llamo a esto "_searchAreaViewController". Esto es importante, incluso si usted no siempre accede al controlador de vista (pero recuerde, usted tiene que liberarlo en algún momento)

@interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate, UITableViewDelegate, UITableViewDataSource> { 

    UIPopoverController *popoverController; 
    UIToolbar *toolbar; 

    id detailItem; 
    UILabel *detailDescriptionLabel; 

    IBOutlet UIViewController* _searchAreaViewController; 
} 

2) hacer que la vista que contiene para su área de búsqueda de la vista de esta nueva controlador de vista. Para hacer esto, use Interface Builder para establecer una nueva salida de referencia para esta vista arrastrando la salida a searchAreaViewController y seleccionando la salida "view". Debe tener una vista contenedora: debe ser una subvista de su vista detallada, y debe contener UISearchBar y probablemente su UITableView.

3) hacer que la propiedad searchContentsController del UISearchDisplayController se refiera a este nuevo controlador de vista en lugar de a detail-view-controller. Esto solo se puede hacer a través de Interface Builder ya que la propiedad es de solo lectura (IB tiene algo de magia para hacer que esto funcione). Si necesita hacer este paso a través del código, tendrá que subclasificar el UISearchDisplayController y devolver el valor correcto de un anulación de propiedad de "searchContentsController".

Hice una aplicación de muestra para demostrar esto y la única línea de código que tuve que agregar a la plantilla SplitView fue la que figura en el paso 1 anterior. Todo lo demás era simplemente agregar las vistas/controladores y conectarlos adecuadamente en IB.

buena suerte!

+0

Después de hacer eso, el área todavía se oscurece ... Mi única duda es en el paso número 2. Al vincular la vista al controlador de vista, se convierte en una salida tanto para el controlador de vista de detalles como para el buscadorAvistaViewController. ¿Es eso correcto? Si elimino la referencia al controlador de vista detallada, la aplicación se bloquea al inicio. –

+0

No, solo debería ser la vista para el nuevo "searchAreaViewController". Esta vista debe ser una subvista de la vista de DetailViewController. ¿Es eso lo que tienes? – TomSwift

+1

Aquí, publiqué un proyecto de muestra para usted, aquí: http://goo.gl/Gv1NH – TomSwift

0

¿Podría aclarar a qué se refiere con "use la barra de búsqueda" y "atenúa todo lo presente"? Interpreto lo que escribió de tal manera que el teclado aparece cuando está a punto de ingresar texto en el campo de texto de la barra de búsqueda. Y que en este punto, la vista de detalles está atenuada, lo que impide la interacción del usuario.

La causa es que la barra de búsqueda implementa un diálogo modal que impide la interacción del usuario con la vista, siempre y cuando se muestre el teclado.Lamentablemente, no parece haber ninguna forma de configurar la barra de búsqueda para evitar este comportamiento. Por otro lado, no estoy seguro de que el usuario no espere este comportamiento, ya que las barras de búsqueda son modales consistentemente y se comportan así en general en iOS.

me han tratado dos soluciones temporales:

1.) Hay una propiedad de la llamada UIViewControllermodalPresentationStyle que produce exactamente el comportamiento describiría si tiene el valor UIModalPresentationFormSheet ("Todas las áreas no cubiertas están atenuados para prevenir el usuario puede interactuar con ellos ", ver Apple documentation). Pero establecer esta propiedad en valores diferentes no cambia el resultado (al menos para mí no funcionó).

2.) Debería escribir su propia barra de búsqueda de reemplazo no modal ya que un UITextField estándar no es modal y por lo tanto no atenúa ningún otro elemento de la IU. Este enfoque funciona, pero es posible que necesite un poco más de trabajo para que se vea como una barra de búsqueda "normal". Pero, una vez más, dado que esta barra de búsqueda se comporta de forma diferente a las barras de búsqueda normales modales en iOS, puede que en realidad no sea lo que esperan los usuarios.

0

Sé que llego tarde y esta es una idea horrible aquí, pero 'setHidden: No' no funcionó para mí.

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 

BOOL hasBeenremoved = NO; 
hasBeenremoved = [[[[NSThread mainThread] threadDictionary] objectForKey:@"hasBeenremoved"] boolValue]; 

if (hasBeenremoved) 
{ 
    UIView* dimmingView = nil; 
    dimmingView = [[[NSThread mainThread] threadDictionary] objectForKey:@"dimmingView"]; 

    UIView* dimmingViewSuperView = nil; 
    dimmingViewSuperView = [[[NSThread mainThread] threadDictionary] objectForKey:@"dimmingViewSuperView"]; 

    [dimmingViewSuperView addSubview:dimmingView]; 

    [[[NSThread mainThread] threadDictionary] setObject:@NO forKey:@"hasBeenremoved"]; 
} 

if ([searchText length] == 0 || [searchText isEqualToString:@""]) 
    { 
     [searchBar becomeFirstResponder]; 
     [[[self primarySearchDisplayController] searchResultsTableView] reloadData]; 
     [[[self primarySearchDisplayController] searchResultsTableView] setHidden:NO]; 

     for(UIView *subview in self.view.subviews) 
     { 
      if([subview isMemberOfClass:[UIControl class]] || 
       ([[[subview class] description] isEqualToString:@"UISearchDisplayControllerContainerView"])) 

      { 
       for(UIView *subView2 in subview.subviews) 
       { 
        for(UIView *subView3 in subView2.subviews) 
        { 
         if (subView3.alpha < 1) 
         { 


          if ([[[subView3 class] description] isEqualToString:@"_UISearchDisplayControllerDimmingView"]) 
          { 
           [[[NSThread mainThread] threadDictionary] setObject:subView3 forKey:@"dimmingView"]; 
           [[[NSThread mainThread] threadDictionary] setObject:subView3.superview forKey:@"dimmingViewSuperView"]; 

           [[[NSThread mainThread] threadDictionary] setObject:@YES forKey:@"hasBeenremoved"]; 

           [subView3 removeFromSuperview]; 
          } 


         } 
        } 
       } 
      } 
     } 
    } 
} 
1

iOS 8+

[[UIView appearanceWhenContainedInInstancesOfClasses:@[NSClassFromString(@"UISearchDisplayControllerContainerView")]] setHidden:YES]; 

iOS 7

que sé, que UISearchDisplayController está en desuso por ahora, pero si todavía hay que usarla, puede resolver su problema con una línea de código perfectamente. Agrégalo al método viewDidLoad.

+0

Esta respuesta no parece agregar nada significativo a la pregunta. Si esto es discutir nuevos cambios que otros desarrolladores deben tener en cuenta, ya que las otras respuestas han sido publicadas, por favor aclare abundantemente en su respuesta ya que esta pregunta es muy antigua. Mejor aún, sugiera una edición a la respuesta adecuada para actualizarla. – Ghedipunk

+0

@Ghedipunk, creo que estás equivocado y esta respuesta agrega algo significativo, porque otros desarrolladores ahora no podían pasar mucho tiempo luchando e implementando tantos pasos como antes. PD La respuesta fue actualizada. –

+0

Luego use más de 2 líneas de código y un párrafo mal escrito para explicar por qué esto agrega algo significativo. – Ghedipunk