2009-05-27 13 views
11

Estoy tratando de hacer algo que no debería ser tan complicado, pero no puedo resolverlo. Tengo un UIViewController que muestra una UITableView. Quiero presentar un menú contextual cuando el usuario presiona sobre una fila. Quiero que sea una vista semitransparente con etiquetas y botones. Podría usar un AlertView, pero quiero un control total sobre el formato de las etiquetas y botones y me gustaría usar el Interface Builder.iPhone Modal View Más pequeño que la pantalla

Así que creé mi pequeña vista de 250x290, configuré el alfa en .75 y creé un controlador de vista con las tomas de corriente para manejar los diferentes eventos del usuario.

Ahora quiero presentarlo. Si uso presentModalViewController ocurren dos cosas (no deseadas) 1) la vista cubre toda la pantalla (pero la barra de estado). 2) Es semitransparente, pero lo que veo "detrás" no es la vista principal sino la vista raíz de la aplicación.

He intentado añadir como un subvista, pero no pasa nada, así que no estoy haciendo algo bien:

RestaurantContextVC* modalViewController = [[[RestaurantContextVC alloc] initWithNibName:@"RestaurantContextView" bundle:nil] autorelease]; 
[self.view addSubview:modalViewController.view]; 

¿Es posible hacer lo que quiero? Gracias de antemano.

Gonso

+0

Hola Gonso! Estoy tratando de hacer lo mismo. En su solución final, ¿terminó teniendo la vista modal emergente más pequeña? (Tu publicación a continuación sugiere problemas con el fondo padre aún interactivo). ¿Encontró una forma de desactivar la interacción táctil con la pantalla principal mientras se mantiene la vista modal más pequeña (además de la transparencia parcial, el usuario aún puede ver la información principal alrededor de los bordes de la subvista modal)? El rect redondo funciona para mí, pero me preocupa que el usuario toque la vista modal y obtenga una respuesta inesperada. Quiero que los únicos botones de retorno posibles sean los de la vista modal. – Cindeselia

Respuesta

11

Estoy codificando algo similar. Mi enfoque incluye .....

  1. No usar dismissModalViewControllerAnimated y presentModalViewController: animada.

  2. Diseñe una vista personalizada de tamaño completo en IB. En su cuerpo de mensaje viewDidLoad, establezca el color de fondo en clearColor, de modo que el espacio en la vista no cubierto por los controladores sea transparente.

  3. Puse un UIImageView bajo los controladores de la vista flotante. El UIImageView contiene una imagen abierta, que tiene esquinas redondeadas y el fondo se establece en transparente. Esta vista de imagen sirve como contenedor.

  4. Uso CoreAnimation para presentar/descartar la vista flotante en el estilo de vista modal: (FloatingViewController.m)

    - (void)viewDidLoad 
    { 
        [super viewDidLoad]; 
        [self.view setBackgroundColor:[UIColor clearColor]]; 
    
        [UIView beginAnimations:nil context:nil]; 
        [self.view setFrame:CGRectMake(0, 480, 320, 480)]; 
    
        [UIView setAnimationDuration:0.75f]; 
        [self.view setFrame:CGRectMake(0, 0, 320, 480)]; 
        [UIView commitAnimations]; 
    } 
    
+0

el fondo se ve negro si configuro el color para borrar –

2

Me gustaría considerar seriamente el uso de un controlador de navegación para deslizarse en su subvista en lugar de la superposición de la misma. Este es el modelo esperado y cualquier pequeño beneficio que pienses que obtendrás si lo haces a tu manera se verá enormemente compensado por el principio de (mínima) sorpresa.

Si realmente tiene que hacerlo de esta manera, creo que el truco consiste en agregar la primera vista de tabla como una subvista de una vista transparente de "retención" que mantiene el controlador de vista. A continuación, agregue su nueva subvista como otra subvista de eso.

+0

¿Se puede agregar una vista pequeña sobre la vista principal usando el controlador de navegación? Supongo que para diseñar una vista completa con controles en ella como una vista pequeña y establecer el fondo como transparente? –

+0

Tengo la misma pregunta: ¿es posible una superposición de vista pequeña? No quiero cubrir toda la pantalla con una diapositiva tampoco, aunque no es el "deslizamiento" el que me molesta, sino la cobertura completa. Quiero mantener al padre parcialmente visible porque el usuario se beneficia al conocer otras opciones además de la que generó la subvista. Yo también quiero establecer el fondo como transparente, pero sin habilitar la interacción con la pantalla trasera mientras la vista modal está activa. La vista modal tendría un botón para cancelar, un UIImageView desplegable detallado (alternar entre las imágenes) y un botón de confirmación. ¡Gracias! – Cindeselia

1

Nuevamente, si realmente desea hacer esto, en lugar de agregar una vista transparente de "retención", ya que esta ventana emergente es esencialmente modal, la convertiría en una subvista directamente de la ventana.

Es posible que desee colocar un escudo negro transparente detrás para evitar toques en el fondo y enfocar la entrada en la ventana emergente.

Pero, en serio, considere abrir un controlador en la pila o usar esa vista de alerta. A menos que haya contratado a un diseñador de $$, probablemente no se vea apropiado en el iPhone.

3

wangii

Eso es más o menos la solución que encontré. me carga la vista con loadNibNamed y luego a añadir en la parte superior con addSubview, así:

//Show a view on top of current view with a wait indicator. This prevents all user interactions. 
-(void) showWaitView{ 
    NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"WaitView" owner:self options:nil]; 
#ifdef __IPHONE_2_1 
    waitView = [ nibViews objectAtIndex: 0]; 
#else 
    waitView = [ nibViews objectAtIndex: 1]; 
#endif   
    CGFloat x = self.view.center.x - (waitView.frame.size.width/2); 
    CGFloat y = self.view.center.y - (waitView.frame.size.height/2); 
    [waitView setFrame:CGRectMake(x,y,waitView.bounds.size.width,waitView.bounds.size.height)]; 
    [self.view addSubview:waitView];  
} 

Podría elaborar sobre los puntos 3 y 4?

Lo que hice para dar la vista, el aspecto recto redondo, es ponerlo dentro de un botón recto redondo.

Este código realmente le permitirá tener una vista flotante pequeña, pero si la vista es más pequeña que su elemento primario, el usuario podría interactuar con la parte visible del elemento principal.

Al final creo mi vista con el mismo tamaño, pero guardo el código por si acaso.

Gonso

+0

¿WaitView es un UIView o un ViewController? Probé tu código y me dijo que waitView no tiene un marco. También tengo una semilla preparada, pero no puedo convertir una pantalla de plumillas en una UIView, ¡solo un UIViewController! – Cindeselia

1

Lo que hice fue crear un UIViewController en la parte superior de mi controlador de UINavigation en mi aplicación delegado y lo hizo de una propiedad de un objeto único para mayor comodidad:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

//--- create root navigation controller 
self.window.rootViewController = self.navigationController; 

//--- create view controller for popups: 
popupViewController = [[BaseViewController alloc] init]; 
popupViewController.view.backgroundColor = [UIColor clearColor]; 
popupViewController.view.hidden = true; //for rendering optimisation 
[self.window addSubview:popupViewController.view]; 
[AppState sharedInstance].popupViewController = self.popupViewController; 

//--- make all visible: 
[self.window makeKeyAndVisible]; 

return YES; 

}

En cualquier punto de mi aplicación, puedo llamar, por ejemplo

MyViewController * myVC = [[UIViewController alloc] init]; 
//... set up viewcontroller and its view... 
// add the view of the created view controller to the popup view: 
[AppState sharedInstance].popupViewController.view.hidden = false; 
[[AppState sharedInstance].popupViewController.view addSubview:myVC.view]; 

El BaseViewController utiliza en la parte superior simplemente hereda de UIViewController y establece una vista de pantalla completa:

//----- in BaseViewController implementation 
- (void)loadView { 
    //------- create root view: 
    CGRect frame = [[AppState sharedInstance] getScreenFrame]; 
    rootView = [[VCView alloc] initWithFrame:frame]; 
    rootView.backgroundColor = [UIColor whiteColor]; 
    self.view = rootView; 
} 
Cuestiones relacionadas