Ich aktualisiere meine App für iOS 7 und habe ein seltsames Problem entdeckt. Ich präsentiere einen UIViewController, der in einen UINavigationController mit eingeschlossen ist UIModalTransitionStyleFlipHorizontal
.
In iOS 6 funktioniert es einwandfrei, aber in iOS 7 springt die Navigationsleiste nach dem Übergang. Hat das etwas mit der Statusleiste zu tun? Ich habe die Transluzenz der Hauptnavigationsleiste auf eingestellt NO
.
In der Info.plist ist das Erscheinungsbild der View Controller-basierten Statusleiste auf NO gesetzt.
Und hier ist ein GIF, das das Problem in einer minimalen Demo-App zeigt:
Hier ist mein Code:
feedNavigationController = [[UINavigationController alloc] init];
feedNavigationController.navigationBar.translucent = NO;
SettingsViewController *settingsVC = [[SettingsViewController alloc] init];
feedNavigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[feedNavigationController setViewControllers:[NSArray arrayWithObjects:settingsVC, nil]];
[self presentViewController:feedNavigationController animated:YES completion:nil];
Antworten:
Dies scheint ein UIKit-Fehler zu sein. Die folgende Problemumgehung scheint das Problem für mich zu lösen.
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.navigationController.navigationBar.layer removeAllAnimations]; }
(Legen Sie diese im View - Controller Sie den Übergang zu ).
quelle
Um dieses Problem zu lösen und zu entlassen, verwende ich den benutzerdefinierten Übergang für iOS7.
Fügen Sie dies Ihrem UIViewController hinzu:
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { return (id<UIViewControllerAnimatedTransitioning>)self; } - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { return (id<UIViewControllerAnimatedTransitioning>)self; } - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { return 0.7f; } - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { UIView *containerView = [transitionContext containerView]; UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; [containerView addSubview:fromVC.view]; UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; [containerView addSubview:toVC.view]; UIViewAnimationOptions animationOption = ([toVC.presentedViewController isEqual:fromVC])?UIViewAnimationOptionTransitionFlipFromLeft:UIViewAnimationOptionTransitionFlipFromRight; [UIView transitionFromView:fromVC.view toView:toVC.view duration:[self transitionDuration:transitionContext] options:animationOption completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; }
Um es zu verwenden, mussten Sie nur überprüfen, ob Sie unter iOS7 arbeiten, und das TransitionDelegate festlegen:
YourVCWithTheCustomTransition* yourVC = [[YourVCWithTheCustomTransition alloc] init]; CGFloat deviceVersion = [UIDevice currentDevice].systemVersion.floatValue; if(deviceVersion >= 7.0) [yourVC setTransitioningDelegate:yourVC]; [self presentModalViewController:yourVC animated:YES]; [yourVC release];
In meinem Fall hatte ich einen benutzerdefinierten UINavigationController, in dem der benutzerdefinierte Übergang definiert ist: Ich muss dies nicht jedes Mal tun.
quelle
if ([yourVC respondsToSelector:@selector(setTransitioningDelegate:)] { [yourVC setTransitioningDelegate:yourVC]; }
Dies scheint ein UIKit-Fehler zu sein. Die folgende Problemumgehung scheint das Problem für mich zu lösen.
presentViewController
(Platzieren Sie dies in dem Ansichts-Controller, zu dem Sie wechseln):- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.navigationController.navigationBar.layer removeAllAnimations]; }
dismissViewControllerAnimated
(Platzieren Sie dies in dem View Controller, den Sie schließen):- (void)viewWillLayoutSubviews{ [super viewWillLayoutSubviews]; [self.navigationController.navigationBar.layer removeAllAnimations]; }
wenn Sie nicht verwenden
autolayout
. Sie müssen dies dem Ansichts-Controller hinzufügen, zu dem Siedismiss
:- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.view setNeedsLayout]; }
quelle
Ich hatte das gleiche Problem und konnte es "lösen" (es ist keine echte Lösung für das Problem, aber es sieht gut aus :)). Der Trick besteht darin, dass der Ansichts-Controller mit
pushViewController
/popViewController
mit einerUIView
Animation einen Flip ausführt. Hier ist ein Beispielcode zur Darstellung des View Controllers:UIViewController *viewController = [[UIViewController alloc] init]; [UIView transitionWithView:self.navigationController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ [self.navigationController pushViewController:viewController animated:NO]; } completion:nil];
Um es zu entlassen:
[UIView transitionWithView:self.navigationController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{ [self.navigationController popViewControllerAnimated:NO]; } completion:nil];
Wenn Sie nicht möchten, dass der
navigationBar
auf dem Push-Controller ist, rufen Sie einfach[self.navigationController setNavigationBarHidden:YES animated:NO]
anviewWillAppear
. Ich hoffe, dieser Ansatz hilft Ihnen.quelle
Sowohl für den präsentierenden als auch für den präsentierten Ansichts-Controller habe ich einen
UITableViewController
InnenbereichUINavigationController
, der beide mithilfe des automatischen Layouts konfiguriert wurde. Ich bemerkte, dass die anderen Antworten das Problem nicht lösten, dass beim Schließen der tableView des präsentierenden View-Controllers 20 pt vertikal springt.Diese Lösung behebt dieses Problem.
In der vorgestellten Ansichtssteuerung (wie von Ben Packard vorgeschlagen):
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.navigationController.navigationBar.layer removeAllAnimations]; }
In der darstellenden Ansichtssteuerung (wie teilweise von staubig vorgeschlagen):
- (void)viewWillLayoutSubviews{ if (self.navigationController.presentedViewController) { [self.navigationController.navigationBar.layer removeAllAnimations]; [self.tableView.layer removeAllAnimations]; } [super viewWillLayoutSubviews]; }
quelle
Das gleiche für mich. Was tatsächlich funktioniert hat, ist, den Stil in CoverVertical zu ändern, sieht viel flüssiger aus.
quelle