IOS 7用にアプリを更新していますが、奇妙な問題を発見しました。 UIModalTransitionStyleFlipHorizontal
を使用してUINavigationControllerにラップされたUIViewControllerを提示しています。
IOS 6では正常に動作しますが、iOS 7では、移行後にナビゲーションバーがバウンスします。これはステータスバーと関係がありますか?メインナビゲーションバーの半透明度をNO
に設定しました。
Info.plistでは、View controller-based status bar appearがNOに設定されています。
そして、これが最小限のデモアプリでの問題を示すGIFです。
これが私のコードです:
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];
これはUIKitのバグのようです。次の回避策で問題が解決したようです。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController.navigationBar.layer removeAllAnimations];
}
(これを、移行するビューコントローラーに配置しますto)。
この問題を解決して解決するには、iOS7カスタムトランジションを使用します。
これをあなたのUIViewControllerに追加してください:
- (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];
}];
}
これを使用するには、iOS7を使用しているかどうかを確認し、transitionDelegateを設定するだけです。
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];
私の場合、カスタム遷移が定義されているカスタムUINavigationControllerがありました。毎回これを行う必要はありません。
これはUIKitのバグのようです。次の回避策で問題が解決したようです。
presentViewController
(これを移行先のビューコントローラーに配置します):
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController.navigationBar.layer removeAllAnimations];
}
dismissViewControllerAnimated
(これを却下するビューコントローラーに配置します):
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
[self.navigationController.navigationBar.layer removeAllAnimations];
}
autolayout
を使用しない場合。これをdismiss
のビューコントローラに追加する必要があります。
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.view setNeedsLayout];
}
私は同じ問題を抱えており、「解決する」ことができました(それは問題の実際の解決策ではありませんが、問題なく見えます:))。トリックは、フリップフロップを作成するためにpushViewController
アニメーションでpopViewController
/UIView
を使用してビューコントローラを表示することです。以下は、ビューコントローラーを表示するコードの例です。
UIViewController *viewController = [[UIViewController alloc] init];
[UIView transitionWithView:self.navigationController.view
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[self.navigationController pushViewController:viewController animated:NO];
}
completion:nil];
それを閉じるには:
[UIView transitionWithView:self.navigationController.view
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[self.navigationController popViewControllerAnimated:NO];
}
completion:nil];
プッシュされたコントローラーでnavigationBar
が不要な場合は、viewWillAppear
の[self.navigationController setNavigationBarHidden:YES animated:NO]
を呼び出します。このアプローチがお役に立てば幸いです。
提示するビューコントローラーと提示されるビューコントローラーの両方について、UITableViewController
内にUINavigationController
があり、どちらも自動レイアウトを使用して構成されています。他の回答では、表示するビューコントローラーのtableViewを閉じると垂直方向に20 ptジャンプするという問題が解決されないことに気付きました。
このソリューションはこの問題に対処します。
提示されたビューコントローラー(Ben Packardによって提案されたもの)で:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController.navigationBar.layer removeAllAnimations];
}
プレゼンテーションビューコントローラで(部分的にほこりっぽく提案されているように):
- (void)viewWillLayoutSubviews{
if (self.navigationController.presentedViewController) {
[self.navigationController.navigationBar.layer removeAllAnimations];
[self.tableView.layer removeAllAnimations];
}
[super viewWillLayoutSubviews];
}