2010-01-27 10 views
10

En algunos de mis diseños de aplicaciones o solo para algunos UIViews, siguiendo el control de vista pushViewController, mi nueva vista se desplazará fuera de la ventana por la altura de la barra de estado. Como resultado, pondré este código auxiliar en el método viewDidLoad.¿Por qué algunos de mis UIViews se desplazan después de la navegación?

CGRect frameAt = [self.view frame]; 
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; 
frameAt.origin.y += statusBarFrame.size.height; 
[self.view setFrame: frameAt]; 

No tiene sentido para mí que esta es la intención de XCode y el Interface Builder, así que sospecho que estoy haciendo algo fundamentalmente equivocado con el SDK durante mi vista de diseño. Además, en la rara ocasión en que no tengo que cambiar mi punto de vista, realmente no sé cuál es la diferencia en los dos enfoques de diseño.

Tenga en cuenta también que la mayoría de las veces trato de diseñar mis vistas utilizando IB, con algunas personalizaciones menores.

¿Alguien más se encuentra con esto y sabe lo que hacen para arreglar sin tal código?

+0

También tenga en cuenta que he jugado con la configuración 'estado simulado' y al menos una vez, que apareció hacer el ajuste correcto para que no tenga que hacer el cambio en el código. – mobibob

Respuesta

16

He usado Apple's NavBar sample code para tratar de reproducir este problema.

la applicationDidFinishLaunching está implementado originalmente como esto:

[window addSubview:navigationController.view]; 
[window makeKeyAndVisible]; 

Si cambio a esto:

UIViewController *shellController = [[UIViewController alloc] initWithNibName:nil bundle:nil]; 
[shellController.view addSubview:navigationController.view]; 
[window addSubview:shellController.view]; 
[window makeKeyAndVisible]; 

entonces consigo la aparición de huecos.

Sin embargo, si sólo hago esto:

UIView *shell = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
[shell addSubview:navigationController.view]; 
[window addSubview:shell]; 
[window makeKeyAndVisible]; 

Luego todo se ve normal.

Supongo que cada controlador de vista compensará su vista si es el controlador de vista raíz. Pero el controlador de navegación anula este comportamiento para compensar su vista independientemente de si es el controlador de la vista raíz. Por lo tanto, diría que su brecha está apareciendo porque tiene un controlador de navegación en algún lugar inferior de la jerarquía de lo que se supone que debe ser.

+0

Creo que estás en el problema. Voy a verificar mi otra aplicación que tiene dos de sus pantallas con este problema. Creo que puedo haber agregado un UINavigationController a esos UIViewControllers. De vuelta en unos 20 minutos ... – mobibob

+0

Misterio resuelto! ¡¡¡Eso es!!! Realmente aprecio tu diligencia al profundizar en esto. Aprendí un gran principio para agregar una barra de navegación a los UIViewControllers existentes.Como los tenía, se definieron como "inferiores en la jerarquía de UIView"; de modo que cuando los agregué como IBOutlet en el código, formulé una instancia en IB y enganché el controlador de navegación del IB en IBOutlet de mi código, obtuve tanto la característica de navegación que quería como la ausencia de artefactos de visualización. Además, mi configuración del marco causó un inquietante "salto" para volver a su lugar. Esta es 110% la respuesta correcta a mi problema. – mobibob

+0

Noté que esto fue respondido en marzo, 10. No estoy seguro si esto es compatible con iOS6. Tengo un problema similar, pero el espacio está debajo de la barra de navegación. Aquí está mi pregunta: http://stackoverflow.com/questions/17790946/ios-containerview-with-modalview-gap-appears-after-dismissing-modal Gracias. – user1107173

2

Lo más importante a tener en cuenta aquí es que un controlador de vista configurará el marco de su vista. Esto se debe a que la cantidad de espacio disponible para la vista puede cambiar durante la vida útil de la aplicación, y solo el controlador de vista sabe cómo ajustar el marco de la vista de manera apropiada. Los ejemplos de cuándo cambia la cantidad de espacio incluyen la barra de navegación que cambia la altura, el dispositivo se vuelve de vertical a horizontal y la barra de estado también puede aumentar en altura si el usuario está atendiendo una llamada. Debido a esto, no debe modificar el marco de la vista usted mismo.

Por lo tanto, lo primero que debe hacer es eliminar todo el código relacionado con la modificación del marco de la vista.

Ahora necesita diseñar sus puntos de vista pensando que el tamaño del marco podría cambiar en cualquier momento. Esto significa establecer correctamente la propiedad de conversión automática de cada subvista. Si haces esto, entonces no importará si activas las barras de navegación y estado simuladas o no; solo están ahí para ayudarlo a ver cuál será el resultado final en la mayoría de los casos.

Puede establecer la propiedad de aumento automático de cada subvista en el Creador de interfaces en el Inspector de tamaño (el que tiene el icono de regla). En la animación, el cuadro blanco representa la vista raíz del controlador de vista, el cuadro rojo representa la subvista seleccionada actualmente. Notará que la subvista está anclada a la esquina superior izquierda de la vista raíz de forma predeterminada. Esto está bien si el tamaño de la vista nunca cambia, pero sabemos que no es cierto. Si tiene subvistas que quiere que aparezcan en la parte inferior, no importa qué, entonces necesita jugar con el diagrama de la izquierda. La forma en que funciona es si se selecciona una de las cuatro líneas alrededor del borde, entonces la distancia entre ese borde de la vista raíz y el borde de la subvista es fija. Por lo tanto, si desea que aparezca una subvista en la parte inferior, debe asegurarse de que esté seleccionada la línea inferior y no la superior. Las dos líneas en el medio afectan si el tamaño de la subvista cambia cuando la vista raíz cambia de tamaño. Entonces, por ejemplo, si tiene una vista de tabla que desea ocupar toda la altura de la pantalla, se aseguraría de que se haya seleccionado la línea vertical interna. Esto se llama modelo de puntales y muelles.

Si está agregando subvistas por programación, necesita establecer la propiedad de masteringMask en cada subvista. Here's an explanation.

Espero que ayude!

+0

Hola Moshy, supongo que confirmaste lo que creía (deja que el sistema administre las vistas y los marcos). Desafortunadamente, con el tiempo, algo en mi codificación modificará algo y los marcos cambiarán.Por lo general, es la vista de un controlador de vista subclasificado cuando navego y luego regreso. Creo que mi comprensión es (fue) correcta y mi verdadera pregunta debería ser: ¿cómo determino qué hice para ajustar mi jerarquía y qué parámetro/configuración fundamental tengo que corregir? También he leído (varias veces) el documento al que se hace referencia. Haré un poco más de revisión antes de decidir que esta es la respuesta. – mobibob

+0

Moshy, leí las preguntas y respuestas de Brian. Varios de ellos descubrieron que tenían que establecer el cuadro en su propio tamaño, que es lo que también hice. Esto suena como una condición de carrera de tamaño durante la detección de orientación o algo fundamental. Revisaré el autosizing de mis subvistas y si eso funciona, le otorgaré la respuesta. – mobibob

+0

Hmm, podría ser útil publicar la estructura del controlador de visualización. Los documentos especifican: al implementar una interfaz de navegación, debe instalar esta vista como la raíz de la jerarquía de vistas que está creando. Por ejemplo, si está desplegando la interfaz de navegación por sí mismo, haría que esta vista sea la subvista principal de su ventana. Para instalar una interfaz de navegación dentro de una interfaz de barra de pestañas, debe instalar la vista del controlador de navegación como vista raíz de la pestaña correspondiente. – jamesmoschou

1

Me he encontrado con problemas similares.Echa un vistazo a mis dos preguntas anteriores:

IPhone - After dismissing Modal View Controller - gap is left at top of page

IPhone - UIView addSubview Gap at top

+0

Hola Brian, Como mencioné en mis comentarios a Moshy (arriba), revisé tu Q & A (que creo que había investigado antes de hacer mi pregunta) y parecían prometedoras, pero no abordaron mi problema. Además, creo que establecer el cuadro en su configuración actual es la solución equivocada, ya que es más probable que algo esté mal. Voy a dejar el mensaje sin respuesta todavía (he respondido el problema para una de mis aplicaciones, pero no creo que sea la solución para las otras aplicaciones). – mobibob

+0

Lo bueno: estas respuestas fueron útiles para mi I + D del problema y ofrecieron una mayor comprensión del SDK; sin embargo, la respuesta de Moshy resolvió directamente mi problema y tuvo algunos efectos secundarios de limpieza. Es posible que desee revisar su viejo problema y ver si esta es una solución mejor. - Sinceramente gracias por su esfuerzo. – mobibob

0

link text

Un error similar se discuten aquí.

También está la animación establecida en NO? Intente configurarlo en SÍ ya que esto resolvió un problema similar al que estaba enfrentando.

0

La respuesta de Moshy fue muy útil ya que finalmente me di cuenta del significado de las líneas punteadas/sólidas en IB para controlar las propiedades de cambio de tamaño de los elementos UIView.

Sin embargo, el ajuste de esas propiedades no resolvió un problema similar al que enfrenté con uno de mis puntos de vista. Esta vista tenía un estado y una barra superior definidas en IB. Era un poco pesado, que contenía una UIWebView que cargaba una cadena HTML dentro de viewWillAppear y algunos otros elementos de la interfaz.

Al cargar la vista, si el usuario cambia repentinamente la orientación del dispositivo de vertical a horizontal, todo el contenido de la vista se desplazará hacia abajo por la altura de la barra de estado. El espacio resultante entre los controles de vista y su parte superior se mantendría incluso después de volver a la orientación vertical.

Lo que finalmente resuelto mis problemas, y mi pelo restante, fue la adición de la línea:

self.view.frame = [[UIScreen mainScreen] bounds]; 

dentro

-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

Desde mis ver su contenido se mantienen en su lugar a pesar de los cambios de orientación dispositivo bruscos.

Cuestiones relacionadas