iphone - example - despedirModalViewController con transición: de izquierda a derecha
transition swift 4 (3)
Esta clase de Swift 4 ModalService
continuación es una solución flexible preempaquetada que se puede colocar en un proyecto y llamar desde cualquier lugar que sea necesario. Esta clase trae la vista modal en la parte superior de la vista actual desde la dirección especificada, y luego la mueve hacia afuera para revelar la vista original detrás de ella cuando sale. Dado un modalViewController
que se muestra actualmente y un modalViewController
que ha creado y desea mostrar, simplemente llame:
ModalService.present(modalViewController, presenter: presentingViewController)
Luego, para despedir, llamar:
ModalService.dismiss(modalViewController)
Por supuesto, esto se puede llamar desde modalViewController como ModalService.dismiss(self)
. Tenga en cuenta que el descarte no tiene que llamarse desde la presentación del controlador de vista, y no requiere conocimiento o referencia al controlador de la presentación original.
La clase proporciona valores predeterminados razonables, incluida la transición de la vista modal desde la derecha y hacia la izquierda. Esta dirección de transición se puede personalizar pasando una dirección, que se puede personalizar tanto para la entrada como para la salida:
ModalService.present(modalViewController, presenter: presentingViewController, enterFrom: .left)
y
ModalService.dismiss(self, exitTo: .left)
Esto se puede establecer como .left
, .right
, .top
y .bottom
. También puedes pasar una duración personalizada en segundos si lo deseas:
ModalService.present(modalViewController, presenter: presentingViewController, enterFrom: .left, duration: 0.5)
y
ModalService.dismiss(self, exitTo: .left, duration: 2.0)
Diríjase a @jcdmb para la respuesta del Objetivo C a esta pregunta que formó el núcleo de la solución en esta clase.
Aquí está la clase completa. Los valores devueltos por el tipo de transitionSubtype
privado parecen impares pero se configuran de esta manera deliberadamente. Debe probar el comportamiento observado antes de asumir que es necesario ''corregir''. :)
import UIKit
class ModalService {
enum presentationDirection {
case left
case right
case top
case bottom
}
class func present(_ modalViewController: UIViewController,
presenter fromViewController: UIViewController,
enterFrom direction: presentationDirection = .right,
duration: CFTimeInterval = 0.3) {
let transition = CATransition()
transition.duration = duration
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionMoveIn
transition.subtype = ModalService.transitionSubtype(for: direction)
let containerView: UIView? = fromViewController.view.window
containerView?.layer.add(transition, forKey: nil)
fromViewController.present(modalViewController, animated: false)
}
class func dismiss(_ modalViewController: UIViewController,
exitTo direction: presentationDirection = .right,
duration: CFTimeInterval = 0.3) {
let transition = CATransition()
transition.duration = duration
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionReveal
transition.subtype = ModalService.transitionSubtype(for: direction, forExit: true)
if let layer = modalViewController.view?.window?.layer {
layer.add(transition, forKey: nil)
}
modalViewController.dismiss(animated: false)
}
private class func transitionSubtype(for direction: presentationDirection, forExit: Bool = false) -> String {
if (forExit == false) {
switch direction {
case .left:
return kCATransitionFromLeft
case .right:
return kCATransitionFromRight
case .top:
return kCATransitionFromBottom
case .bottom:
return kCATransitionFromTop
}
} else {
switch direction {
case .left:
return kCATransitionFromRight
case .right:
return kCATransitionFromLeft
case .top:
return kCATransitionFromTop
case .bottom:
return kCATransitionFromBottom
}
}
}
}
Estaba usando un buen método para descartar mi controlador de vista modal:
[self dismissModalViewControllerWithTransition:2];
que hace una transición de diapositiva de izquierda a derecha, como lo hace un controlador de navegación para abrir una vista.
Como este método no es público, Apple no lo aceptará. ¿Cómo puedo programar este tipo de animación en mi código (deslice de izquierda a derecha, para descartar una vista modal, y deslice de derecha a izquierda para presentar una vista modal)?
Gracias por adelantado
He aceptado la respuesta de Safecase, pero me gustaría publicar mi solución final aquí:
1) Para presentar un controlador de vista modal con una transición de derecha a izquierda, he escrito el siguiente método:
-(void) presentModalView:(UIViewController *)controller {
CATransition *transition = [CATransition animation];
transition.duration = 0.35;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
// NSLog(@"%s: self.view.window=%@", _func_, self.view.window);
UIView *containerView = self.view.window;
[containerView.layer addAnimation:transition forKey:nil];
[self presentModalViewController:controller animated:NO];
}
2) Para descartar una vista modal con una transición de diapositiva de izquierda a derecha:
-(void) dismissMe {
CATransition *transition = [CATransition animation];
transition.duration = 0.35;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromLeft;
// NSLog(@"%s: controller.view.window=%@", _func_, controller.view.window);
UIView *containerView = self.view.window;
[containerView.layer addAnimation:transition forKey:nil];
[self dismissModalViewControllerAnimated:NO];
}
¡Gracias chicos!
Prueba esto:
Supongo que está retirando un controlador de vista 2 del controlador de vista 1. En el controlador de vista 2, está usando esto
[self dismissModalViewControlleAnimated: NO]];
Ahora en el primer controlador de vista, en viewWillAppear: método agregar el código
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setDuration:0.50];
[animation setTimingFunction:
[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseInEaseOut]];
[self.view.layer addAnimation:animation forKey:kCATransition];