Jak „anulować” wyświetlanie przejść wyglądu dla niestandardowych przejść kontrolera kontenera

Stworzyłem niestandardowy kontroler kontenera, który działa podobnie do aUIPageViewController abym mógł zaimplementować niektóre niestandardowe przejścia i logikę źródła danych. Starałem się naśladować sposób, w jaki nowe interfejsy API zmiany kontrolera widoku klienta działają w systemie iOS 7, i działa dobrze, z wyjątkiem niektórych irytujących dziwactw z wywołaniami zwrotów wyglądu podczas przejściaanulowany...

Mianowicie, podczas wykonywania przejścia, kiedy dokładnie powinnobeginAppearanceTransition:animated: iendAppearanceTransition być wezwanym?

Moja niestandardowa klasa kontenera ma taki kod:

- (BOOL)shouldAutomaticallyForwardAppearanceMethods
{
    return NO;  // Since the automatic callbacks are wrong for our custom transition.
}

- (void)startTransition:(CustomTransitionContext *)context
{
    // Get reference to the view controllers involved in the transition.
    UIViewController *oldVC = [context viewControllerForKey:UITransitionContextFromViewController];
    UIViewController *newVC = [context UITransitionContextToViewController];

    // Prepare parent/child relationship changes.
    [oldVC willMoveToParentViewController:nil];
    [self addChildViewController:newVC];

    // Begin view appearance transitions.
    [oldVC beginAppearanceTransition:NO animated:[context isAnimated]];
    [newVC beginAppearanceTransition:YES animated:[context isAnimated]];

    // Register a completion handler to run when the context's completeTransition: method is called.
    __weak CustomContainerController *weakSelf = self;
    context.transitionCompletionHandler = ^(BOOL complete) {
        // End appearance transitions here?
        [oldVC endAppearanceTransition];
        [newVC endAppearanceTransition];

        if (complete) {
            // Or only if the transition isn't cancelled; here?
            [oldVC endAppearanceTransition];
            [newVC endAppearanceTransition];

            [oldVC removeFromParentViewController];
            [newVC didMoveToParentViewController:weakSelf];
        } else {
            [newVC removeFromParentViewController];
            [oldVC didMoveToParentViewController];
        }
    }

    if ([context isInteractive] && [self.transitionController conformsToProtocol:@protocol(UIViewControllerInteractiveTransitioning)]) {
        // Start the interactive transition.
        [self.transitionController startInteractiveTransition:context];
    } else if ([context isAnimated] && [self.transitionController conformsToProtocol:@protocol(UIViewControllerAnimatedTransitioning)]) {
        // Start the animated transition.
        [self.transitionController animateTransition:context];
    } else {
        // Just complete the transition.
        [context completeTransition:YES];
    }
}

Więc jeśli zadzwonięendAppearanceTransition niezależnie od tego, czy przejście zostało anulowane, moje wywołania zwrotne widoku wyglądają następująco, gdy przejście zostanie anulowane:

oldVC viewWillDisappear:  // Fine
newVC viewWillAppear:     // Fine
// ... some time later transition is cancelled ...
oldVC viewDidDisappear:   // Wrong! This view controller's view is staying.
newVC viewDidAppear:      // Wrong! The appearance of this view controllers view was cancelled.

Jeśli zadzwonięendAppearanceTransition tylko kiedy przejście zakończy się pomyślnie, na początku wszystko wygląda lepiej:

oldVC viewWillDisappear:  // Fine
newVC viewWillAppear:     // Fine
// ... some time later transition is cancelled ...
// ... silence. (which is correct - neither view actually appeared or disappeared,
//               and I can undo side effects in viewWill(Dis)Appear using the 
//               transitionCoordinator object)

Ale kiedy następnym razem rozpocznę przejście, otrzymambez wywołań zwrotnych wyglądu. Następny zestaw wywołań zwrotnych wyglądu pojawia się dopiero pobeginAppearanceTransition:animated: po którym następujeendApperanceTransition połączenie. Warto zauważyć, że janie otrzymuj często zgłaszane „Niesymetryczne wywołania przejść do wyglądu początku / końca dla ViewController„ostrzeżenie konsoli.

WWWDC 2013 Session 218 (Niestandardowe przejścia przy użyciu kontrolerów widoku) Bruce Nilo żartuje sobie z tego, że koledzy mu to mówiąviewWillAppear: & viewWillDisappear: naprawdę powinno się nazywaćviewMightAppear: & viewMightDisappear: (zobacz sekcję tej sesji rozpoczynającą się o 42:00). Biorąc pod uwagę, że jesteśmy teraz w sferze anulowalnych interaktywnych gestów, wydaje się, że potrzebujemycancelAppearanceTransition (lubendAppearanceTransition:(BOOL)finished) metoda dla kontenerów niestandardowych.

Czy ktoś wie, co robię źle? Czy można anulować, niestandardowe przejścia w niestandardowych kontenerach po prostu nie są jeszcze poprawnie obsługiwane?

questionAnswers(1)

yourAnswerToTheQuestion