Comportamiento extraño del botón de cancelación de UIActionSheet

116

Tengo un UIBarButtonItem que abre una hoja de acción para ofrecer a los usuarios opciones sobre qué hacer. Todo funciona como se esperaba a menos que intente hacer clic en el botón "Cancelar". El objetivo del botón parece haberse movido hacia arriba desde donde debería estar. Solo puedo activarlo haciendo clic en algún lugar en el medio de los botones "Cancelar" y "Aceptar".

Probé hojas de acción en otras aplicaciones y funcionan bien, así que no es solo mi pulgar. La hoja de acción se abre en un UIViewController

- (void)showOpenOptions
{
    UIActionSheet *sheet = [[UIActionSheet alloc] 
    initWithTitle:NSLocalizedString(@"Open link in external application?", @"Open in external application")
    delegate:self
    cancelButtonTitle:NSLocalizedString(@"Cancel", @"Cancel")
    destructiveButtonTitle:NSLocalizedString(@"Open Link", @"Open Link")
    otherButtonTitles:nil];

    [sheet showInView:self.view];
    [sheet release];
}
rey nevan
fuente
5
En una nota no relacionada, me dijeron en la WWDC durante una sesión de revisión de la interfaz de usuario de Apple que el botón rojo en las hojas de acción está realmente diseñado para acciones 'destructivas' (es decir, 'eliminar').
Ramin
Sí, leí las pautas de interfaz humana recientemente y lo vi. Lo cambié de rojo a gris.
nevan king

Respuestas:

190

En lugar de pasar la vista del controlador de vista actual a la hoja de acciones, use el showFromTabBar:método de UIActionSheet.

La forma correcta
Esto le dará el área correcta para tocar:

[actionSheet showFromTabBar:self.tabBarController.tabBar];

The Wrong Way
Esto colocará el área que se puede tocar en el lugar equivocado (si está usando una barra de pestañas o una barra de herramientas):

[actionSheet showInView:self.view];

Si está utilizando una barra de herramientas , utilice el showFromToolbar:método en su lugar. Necesitará una referencia a la barra de herramientas, probablemente un ivar

[actionSheet showFromToolbar:self.myToolbar];

My Old Answer también funciona, pero es hacky:

Acabo de encontrar una posible respuesta:

01-Dec-2008 10:22 PM Tom Saxton: Miré este error un poco más y parece ser un problema con la barra de pestañas.

Si llama a [sheet showInView: self.view] de UIActionSheet desde un controlador de vista que es hijo de un UITabViewController, entonces la prueba de aciertos en el botón cancelar falla en la parte de UIActionSheet que se encuentra sobre la vista de la barra de pestañas.

Si, en cambio, pasa la vista de UITabBarController, entonces UIActionSheet actúa como se esperaba.

NOTA: en iPhone OS 2.1 y versiones anteriores, UIActionSheet apareció en la parte superior de la barra de pestañas cuando pasa la vista secundaria, pero en 2.2, aparece en la parte inferior de la barra de pestañas y, por lo tanto, cubre la vista de pestañas.

http://openradar.appspot.com/6410780

Editar: funciona correctamente cuando cambio la vista para que sea la vista de la barra de pestañas

[sheet showInView:self.parentViewController.tabBarController.view];
rey nevan
fuente
Voto esto porque funciona. ¿Por qué es esto mejor que las otras respuestas?
Bentford
1
¿Por qué parentViewController? Incluso si la vista está en una vista de navegación, tabBarController debería apuntar al lugar correcto. Funciona para mí sin parentViewController en cualquier caso.
Nathan
11
Otra respuesta parece potencialmente mejor. Busque [actionSheet showInView: [self.view window]]. Parece más sencillo y más genérico.
Kevin
Muchas gracias por publicar esta respuesta.
fulvio
1
No tengo la barra de pestañas en mi aplicación, pero todavía tengo ese problema. Lo resolví con '[ventana de serf.view]'. De todos modos, no es un problema de barra de pestañas.
Mike Keskinov
37

Encontré una respuesta aquí que funciona.

usando [filterActionSheet showInView:[self.view window]]:;

Intenté algunas formas de llegar a mi barra de pestañas y la forma en que está configurada esta aplicación parece complicada ...

driveguy
fuente
¡PERFECTO! Gracias. Esta es la solución correcta para mí, ya que tenía este problema con un UITableViewController que tenía una barra de herramientas, no un TabBar como otros aquí.
William Denniss
buenas cosas, esto funcionó para mí! ¡Esta es definitivamente la forma más fácil de hacerlo!
cgossain
2
Causa otro problema. ActionSheet aparece en orientación vertical cuando el dispositivo está en horizontal (así como el resto del contenido).
Mike Keskinov
22

En su lugar use:

[sheet showFromTabBar:theTabBar];
Corey Floyd
fuente
1
Corregí esto de showInTabBar:a showFromTabBar:. También tenga en cuenta que hay un método 'showFromToolbar:', dependiendo de los muebles de pantalla que tenga en la parte inferior de la pantalla. Creo que esta es una respuesta mejor que la respuesta aceptada.
Stephen Darlington
Stephen, ¿por qué crees que esto es mejor que especificar showInView: theTabBar? Desde una perspectiva de acoplamiento, creo que showInView probablemente sería más ideal, en caso de que más adelante se elimine la barra de pestañas, tal vez se reemplace con una barra de herramientas, por ejemplo. El controlador de vista secundario en particular no debería tener que saberlo o preocuparse, creo.
Billy Gray
Si la barra de pestañas se suelta más tarde, tendrá que editar esa línea de código independientemente (a menos que tal vez la barra de pestañas sea una referencia mal nombrada a una vista que se ha pasado). Entonces no veo cómo este método está más acoplado que showInView: theTabBar. También uso showFromTabBar: ya que me parece más seguro. No sé qué está sucediendo debajo de las sábanas, pero imagino que showFromTabBar: es menos probable que se rompa en futuras versiones del sistema operativo que showFromView: con una vista de barra de pestañas.
Christopher Pickslay
10

Aquí está la solución. Pruebe esto:

[actionsheet showInView:[UIApplication sharedApplication].keyWindow];
Viggnesh
fuente
5

Creo que una combinación de tres de las respuestas es la forma correcta de manejar esto:

    [actionSheet showFromTabBar:self.tabBarController.tabBar];

es decir, use showFromTabBar (por eso existe) y no necesita parentViewController como señaló Nathan (de hecho, self.parentViewController.tabBarController.tabBar devuelve nil para mí.

RawMean
fuente
Por supuesto, devuelve nil, porque el controlador de vista principal (que es el UITabBarViewController) no está anidado en otro UITabBarController, por lo que su propiedad tabBarController es nil.
Dominik Seibold
1

FYI: tuvo el mismo problema con la hoja de acciones de UIDocumentInteractionController al pisar la barra de pestañas. Usé lo siguiente para arreglar.

UIViewController *parentView = [[self parentViewController] parentViewController];
[docController presentOptionsMenuFromRect: rect inView: parentView.view animated:YES];
Mickey
fuente
-2

escribir código simplificado

 actionSheet.actionSheetStyle = UIActionSheetStyleDefault;

esto funciona bien

Jayesh Kavathiya
fuente