IOS7 UIModalTransitionStyleFlipГоризонтальные отскоки после перехода
Я обновляю свое приложение для iOS 7, и я обнаружил странную проблему. Я представляю UIViewController, завернутый в UINavigationController с UIModalTransitionStyleFlipHorizontal
.
В iOS 6 он работает нормально, но в iOS 7 панель навигации отскакивает после перехода. Это имеет какое-то отношение к строке состояния? Я установил прозрачность основной панели навигации на NO
.
В окне Info.plist на панели состояния View на панели управления установлено значение NO.
И вот GIF, показывающий проблему в минимальном демонстрационном приложении:
![enter image description here]()
Вот мой код:
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];
Ответы
Ответ 1
Кажется, это ошибка UIKit. Кажется, что решение этой проблемы разрешает следующее обходное решение.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController.navigationBar.layer removeAllAnimations];
}
(Поместите это в контроллер просмотра, в котором вы переходите в).
Ответ 2
Чтобы решить эту проблему для присутствия и увольнения, я использую пользовательский переход 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 и установите переходDelegate:
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, в котором определен пользовательский переход: я не должен делать это каждый раз.
Ответ 3
Кажется, это ошибка UIKit. Кажется, что решение этой проблемы разрешает следующее обходное решение.
presentViewController (поместите это в контроллер просмотра, к которому вы переходите):
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController.navigationBar.layer removeAllAnimations];
}
rejectViewControllerAnimated (поместите это в контроллер просмотра, который вы уволите):
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
[self.navigationController.navigationBar.layer removeAllAnimations];
}
если вы не используете автоматический макет. вам нужно добавить это к контроллеру вида, который вы упускаете:
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.view setNeedsLayout];
}
Ответ 4
У меня была такая же проблема и я мог "решить ее" (это не реальное решение проблемы, но она выглядит отлично:)). Трюк представляет собой контроллер представления с помощью 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 на толкаемом контроллере просто вызывал [self.navigationController setNavigationBarHidden: YES animated: NO] в viewWillAppear. Я надеюсь, что этот подход поможет вам
Ответ 5
Для представления и представленного контроллера представления у меня есть UITableViewController
внутри UINavigationController
, оба настроены с использованием автоматической компоновки. Я заметил, что другие ответы не решают проблему, что при отключении tableView контроллера представления представления прыгает на 20 pt по вертикали.
Это решение решает эту проблему.
В представленном контроллере представления (как предложено Бен Паккардом):
- (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];
}
Ответ 6
То же самое для меня. Что на самом деле работало, так это изменить стиль на CoverVertical, выглядит намного более плавным.