Así que construí una costumbre presentación de transición de la animación y todo parece estar funcionando muy bien, excepto el controlador de vista del ciclo de vida de los métodos no están siendo llamados a despedir.

Antes de presentar el controlador yo uso el UIModalPresentationCustom estilo para mantener la presentación de VC en la vista de jerarquía, pero una vez que despedir a la presentación de los VC, viewWillAppear y viewDidAppear no se llama en mi presentación de controlador. Me estoy perdiendo un paso que tengo que llamar explícitamente a conseguir esos métodos para el fuego? Sé manualmente llamando a los métodos no es la solución correcta.

Aquí está mi desestimar la animación de código. Estoy básicamente de la animación de una forma de superposición de vista para reducir el tamaño de una colección de células del despido.

- (void)_animateDismissingTransitionWithContext:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UICollectionView *destinationCollectionView = toCollectionViewController.collectionView;
UICollectionViewCell *destinationCollectionViewCell = [self _destinationCellFromContext:transitionContext];
UIView *containerView = transitionContext.containerView;
//Calculate frames    
CGRect startFrame = fromEventDetailViewController.detailContainerView.frame;
CGRect endFrame = [destinationCollectionView convertRect:destinationCollectionViewCell.frame toView:containerView];
//Add overlay
UIView *overlayView = [UIView new];
overlayView.backgroundColor = [UIColor overlayBackground];
overlayView.frame = containerView.bounds;
overlayView.alpha = 1.0f;
[containerView addSubview:overlayView];
//Add fake detail container view
UIView *fakeContainerView = [UIView new];
fakeContainerView.backgroundColor = fromEventDetailViewController.detailContainerView.backgroundColor;
fakeContainerView.frame = startFrame;
[containerView addSubview:fakeContainerView];
//Hide from view controller
fromEventDetailViewController.view.alpha = 0.0f;
[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:0.2f options:UIViewAnimationOptionCurveEaseOut animations:^{
fakeContainerView.frame = endFrame;
fakeContainerView.backgroundColor = [UIColor eventCellBackground];
overlayView.alpha = 0.0f;
} completion:^(BOOL finished) {
[fromEventDetailViewController.view removeFromSuperview];
[overlayView removeFromSuperview];
[fakeContainerView removeFromSuperview];
[transitionContext completeTransition:YES];
}];
}
  • Puede publicar su UIViewControllerAnimatedTransitioning código?
  • Publicado el despido de código. Déjeme saber si cualquier otra información de ayuda.
InformationsquelleAutor Danny | 2014-08-25

6 Comentarios

  1. 36

    Otra solución podría ser el uso de beginAppearanceTransition: y endAppearanceTransition:. De acuerdo a la documentación:

    Si está implementando un contenedor personalizado controlador, el uso de este método
    decirle a un niño que sus opiniones están a punto de aparecer o desaparecer. ¿
    no invocar viewWillAppear:, viewWillDisappear:, viewDidAppear: o
    viewDidDisappear: directamente.

    Aquí es cómo los he usado:

    - (void)animationEnded:(BOOL)transitionCompleted
    {
    if (!transitionCompleted)
    {
    _toViewController.view.transform = CGAffineTransformIdentity;
    }
    else
    {
    [_toViewController endAppearanceTransition];
    }
    }
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
    {
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    [toViewController beginAppearanceTransition:YES animated:YES];
    //... other code
    }

    Pero yo todavía considerar extraño que de costumbre modal presentación no hacerlo.

    • He intentado esto, sin embargo tengo problemas de rotación cuando el usuario hace una actualidad, a continuación, girar a despedir. Mi respuesta a continuación resuelto eso.
    • fromVC viewdiddisappear: todavía no se llama después de que he intentado esto:(
    • debería funcionar si se llama [fromViewController beginAppearanceTransition:NO animado:YES]; y, por supuesto, más tarde [fromViewController endAppearanceTransition];
    • ¿Cómo ven? ¿Por qué no me quieren bandera beginAppearanceTrans como SÍ si llama endAppearance? Voy a probar esto tan pronto como tengo un poco de tiempo libre, no he estado en iOS desde entonces:) Gracias por su respuesta!
    • el bool en este método dice que si se está apareciendo o desapareciendo: isAppearing YES if the child view controller's view is about to be added to the view hierarchy, NO if it is being removed.
  2. 13

    Si usted está usando UIModalPresentationCustom usted debe proporcionar la costumbre UIPresentationController clase, y si desea utilizar ViewController del ciclo de vida de las personas que llaman, que es necesario reemplazar shouldRemovePresentersView y volver YES.

    Si quieres mantener los presentadores y todavía tienen ViewControlelr del ciclo de vida de devolución de llamada, usted puede reemplazar el método privado _shouldDisablePresentersAppearanceCallbacks y volver NO personalizado UIPresentationController clase.

  3. 9

    Después de mucho forcejeo con este problema, he encontrado la mejor solución que funciona en ios7 y ios8 es dejar modalPresentationStyle = UIModalPresentationFullScreen en lugar de UIModalPresentationCustom como los documentos sugieren.

    Si hago esto, así como la configuración de la transitioningDelegate a mi delegado, todavía respeta mi transición y la voluntad/diddisappear métodos llamados en el ‘de’ controlador de vista. También: no-presente, a continuación, girar, luego de despedir a la rotación de los problemas para arrancar.

    • Funciona como un encanto! Gracias.
    • la única manera que puedo conseguir viewDidDisappear: para ser invocada es mediante el uso de su respuesta. PERO, lo que yo intente no puedo conseguir el fromVC a animar. Es como la animación de espera para fromVC a desaparecer. Yo no hago nada para invocar viewdiddisappear a mí mismo. Si me preguntan por contenedor vistas subvistas tanto fromVC y toVC están ahí…
  4. 3

    Ah, este es un referente de la presentación. No creo viewWillAppear y viewDidAppear son llamados con la costumbre de transición utilizando el método, ya que la vista es técnicamente todavía activo en la vista de jerarquía. Me gustaría sugerir el uso de la delegación aquí como lo haría normalmente con una presentados modal.

    Crear delegado de protocolo en la presentación de los VC. Crear un delegado método que puede ser llamado desde la presentación de la VC. Como se presente la superposición, ajuste la presentación de VC como el delegado. A continuación, llamar a ese método delegado de la presentación de los VC. A continuación, puede llamar a cualquier tipo de acciones desde la presentación de VC antes de llamar dismissViewController

    En su superposición (ModalViewController.h):

    @protocol ModalViewDelegate <NSObject>
    -(void)didDismissModalView;
    @end
    @interface ModalViewController : UIViewController
    @property(strong, nonatomic) id <ModalViewDelegate> delegate;

    En su ModalViewController.m, llamar a un método que llama a su método delegado:

    - (void)dismissModal{
    [self.delegate didDismissModalView];
    }

    En su presentación de VC h archivo: (PresentingViewController.h), hacen de esta clase se ajusten a tus modal delegado de protocolo:

    @interface PresentingViewController : UIViewController <ModalViewDelegate>

    En su presentación de VC, como la que presente el modal:

    ...
    ModalViewController *modalViewController = [[ModalViewController alloc] init];
    modalViewController.delegate = self; //the makes the presenting VC the delegate
    [self presentViewController:modalViewController animated:YES completion:nil];
    ...

    Finalmente, en su presentación de VC, cuando se desea realizar algunas acciones antes de despedir el modal, implementar el ModalViewDelegate método:

    - (void)didDismissModalView{
    //DO SOME COOL STUFF, SET UP STUFF HERE, UPDATE UI, ETC
    //Then dismiss the modal
    [self dismissViewControllerAnimated:YES completion:^{
    //Do more cool stuff
    }];
    }

    Todo esto va a trabajar con su actual personalizada código de transición, pero le dará más control sobre lo que sucede antes de que el modal/overlay es despedido. Delegar es una cosa hermosa.

    Además, este va a mantener esta animación de código independiente de código para otras funciones, que es un poco más limpio de la OMI.

    • En lugar de delegar usted simplemente puede llamar viewWillLayoutSubviews,viewWillAppear, viewDidLayoutSubviews,viewDidAppear a la vista y controlador de la inversa de la llamada de la vista controlador
    • Pero para el normal (no custom) presentación de controlador de vista de despedir funciona bien: se llama a todos los métodos. Así que tal vez hay un método especial.
    • de OP post de apple y google docs: Si se implementa un contenedor personalizado controlador, utilice este método para decirle a un niño que sus opiniones están a punto de aparecer o desaparecer. No invocar viewWillAppear:, viewWillDisappear:, viewDidAppear: o viewDidDisappear: directamente. Además se debe utilizar un delegado, si es posible, o usted probablemente será echar a perder las cosas.
  5. 2

    @Juan Tracids’ anser resuelto mi problema. Gracias Juan!

    Pero me gustaría extender una respuesta un poco.

    Si usted está presentando UIViewController instancia con modalPresentationStyle = .custom (objc UIModalPresentationCustom) con el fin de mantener viewcontroller del ciclo de vida de los métodos que se llama, usted tiene que manejar viewcontroller la apariencia de forma explícita. Para hacer esto simplemente llame beginAppearanceTransition antes de animación y endAppearanceTransition en la animación de la finalización del bloque.

    También te puede pasar a su transición animador de la clase personalizada UIPresentationController subclase con reemplazado valor shouldRemovePresentersView regresar true sin llamar beginAppearanceTransition

    //Swift 4

    poner esto a su costumbre UIViewControllerAnimatedTransitioning clase
    antes de animación

    fromViewController.beginAppearanceTransition(false, animated: true)
    toViewController.beginAppearanceTransition(true, animated: true)
    UIView.animate(withDuration: animationDuration, animations: {
    //animation logic…
    }) { finished in
    fromViewController.endAppearanceTransition()
    toViewController.endAppearanceTransition()
    let transitionSuccess = !transitionContext.transitionWasCancelled
    transitionContext.completeTransition(transitionSuccess)
    }
    //UIPresentationController subclass
    class PresentationController: UIPresentationController {
    override var shouldRemovePresentersView: Bool { return true }
    }
  6. 0

    Tengo el mismo problema para llamar a viewWillAppear y otros métodos del ciclo de vida.
    Lo que hice para solucionarlo fue implementado el método delegado func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?

    A continuación, para que funcione tengo que hacer lo siguiente:

    class ViewController: UIViewController {
    ... 
    func showViewController() {
    //load your view controller as you want
    guard let detailViewController = loadDetailViewcontroller()  as? DetailViewController else {
    return }
    detailViewController.modalPresentationStyle = .custom
    detailViewController.transitioningDelegate = self
    present(detailViewController, animated: true, completion: nil)
    }
    }
    extension ViewController: UIViewControllerTransitioningDelegate {
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
    return PresentationController(presentedViewController: presented, presenting: presenting)
    }
    }

    La PresentationController es como un objeto temporal para la presentación.
    La documentación de Apple

    Desde el momento en que un controlador de vista se presenta hasta el momento en que es despedido, UIKit utiliza una presentación de controlador para gestionar diversos aspectos de la presentación del proceso para que el controlador de vista. La presentación controlador puede añadir sus propias animaciones en la parte superior de los proporcionados por el animador de objetos, puede responder a los cambios de tamaño, y se pueden administrar otros aspectos de cómo la vista controlador es presentado en la pantalla.

Dejar respuesta

Please enter your comment!
Please enter your name here