Pregunta

Tengo una transición personalizada en la que intento hacer lo contrario de la transición de transición estándar "Cubierta vertical".Creo que esto debería funcionar:

UIView *srcView = ((UIViewController *)self.sourceViewController).view;
UIView *dstView = ((UIViewController *)self.destinationViewController).view;

[dstView setFrame:CGRectMake(0, 0, srcView.window.bounds.size.width, srcView.window.bounds.size.height)];

[srcView.window insertSubview:dstView belowSubview:srcView];

[UIView animateWithDuration:0.3
     animations:^{
         srcView.center = CGPointMake(srcView.center.x - srcView.frame.size.width, srcView.center.y);
     }
     completion:^(BOOL finished){
         [srcView removeFromSuperview];
     }
 ];

El problema es que la vista de destino aparece en orientación vertical, aunque todas las demás vistas de la aplicación tienen orientación horizontal.Además, las coordenadas xey están invertidas.¿Por qué está pasando esto?

he configurado shouldAutorotateToInterfaceOrientation en cada controlador de vista, pero eso no ayudó.Podría rotar la vista con CGAffineTransformMakeRotation, pero eso no parece ser lo correcto;las coordenadas aún estarían invertidas, para empezar.

Actualizar:

Intenté usar CGAffineTransformRotate para rotar la vista, pero parece ridículo.La mayor parte del fondo aparece negro.No creo que así sea como se supone que funciona.

¿Fue útil?

Solución 3

Aparentemente, fue mucho más fácil de lo que pensé hacer el Segue que quería.Aquí está lo que funcionó:

- (void)perform {
    UIViewController *src = (UIViewController *)self.sourceViewController;
    [src dismissViewControllerAnimated:YES completion:^(void){ [src.view removeFromSuperview]; }];
}

Esperemos que esto ayude a otra persona.

Otros consejos

Dado que no pude obtener la orientación y el encuadre correctos de la vista de destino antes de que intercambiaron los controladores, invierta el proceso:

  1. Guardar la vista de origen como una imagen (consulte Eliminar personalizado UistoryBoardSegue con animación personalizada );
  2. cambiar el controlador actual [redesviewcontroller: ...];
  3. Luego, haga la animación con la vista de destino (ahora correcta) que incorpore la imagen de origen guardado.

    Aquí está el código completo:

    #include <QuartzCore/QuartzCore.h>
    
    @implementation HorizontalSwipingSegue
    
    - (void) perform {
        UIViewController *source = self.sourceViewController;
        UIViewController *destination = self.destinationViewController;    
        UIView *sourceView = source.view;
        UIView *destinationView = destination.view;
    
        // Create a UIImageView with the contents of the source
        UIGraphicsBeginImageContext(sourceView.bounds.size);
        [sourceView.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        UIImageView *sourceImageView = [[UIImageView alloc] initWithImage:sourceImage];
    
        [[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:NULL];
    
        CGPoint destinationViewFinalCenter = CGPointMake(destinationView.center.x, destinationView.center.y);
        CGFloat deltaX = destinationView.frame.size.width;
        CGFloat deltaY = destinationView.frame.size.height;
    
        switch (((UIViewController *)self.sourceViewController).interfaceOrientation) {
           case UIDeviceOrientationPortrait:
                destinationView.center = CGPointMake(destinationView.center.x - deltaX, destinationView.center.y);                
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                destinationView.center = CGPointMake(destinationView.center.x + deltaX, destinationView.center.y);
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
                break;
            case UIDeviceOrientationLandscapeLeft:
                destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y - deltaY);                
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
                break;
            case UIDeviceOrientationLandscapeRight:
                destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y + deltaY);
                sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
                break;
        }
    
        [destinationView addSubview:sourceImageView];
    
        [UIView animateWithDuration:0.6f
                         animations:^{
                             destinationView.center = destinationViewFinalCenter; 
                         }
                         completion:^(BOOL finished){
                             [sourceImageView removeFromSuperview];
                         }];
    }
    
    @end
    

RESPUESTA ACTUALIZADA:

Asegúrese de configurar correctamente el marco de su dstView.Creo que tendrás más suerte usando:

dstView.frame = srcView.frame;

en lugar de:

[dstView setFrame:CGRectMake(0, 0, srcView.window.bounds.size.width, srcView.window.bounds.size.height)];

el bounds La propiedad no reacciona de la misma manera a los cambios de orientación. frame hace.

reemplazar

[srcView insertSubview:dstView belowSubview:srcView];

con

[srcView insertSubview:dstView atIndex:0];

Si solo está agregando la vista de otra vista del controlador a su jerarquía de visualización, ese controlador no va a obtener ninguna información sobre la orientación del dispositivo, por lo que presentará la vista en su configuración predeterminada.Debe agregar el controlador de vista a la jerarquía de controlador de vista, utilizando los métodos de contención descritos aquí .También necesitas eliminarlo de la jerarquía cuando se hace.

También hay varias buenas conversaciones de WWDC sobre el tema, una de 2011 llamada "Contención de Controlador de Vista de Implementación" y una de este año, la evolución de los controladores de vista.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top