Анимация представления представления в UIPresentationController
Для некоторого контекста я рекомендую прочитать это:
Очень актуальный вопрос: "Из View Controller" исчезает с помощью UIViewControllerContextTransitioning Очень актуальный ответ: /questions/30413769/from-view-controller-ischezaet-pri-ispolzovanii-uiviewcontrollercontexttransitioning/30413784#30413784
Я пытаюсь реализовать пользовательский переход контроллера представления, который оживляет новый контроллер представления, чтобы покрыть половину экрана, одновременно сжимая представляющий контроллер представления до 90% (по центру в окне, под представленным контроллером представления).
Во-первых, моя проблема заключалась в том, что viewFromKey:
возвращенный nil
, Чтобы решить это, ответ упоминается:
Если вы хотите анимировать представление контроллеров представления представления, вы должны рассмотреть возможность использования
UIModalPresentationFullscreen
стиль или продолжать использоватьUIModalPresentationCustom
и реализовать свой собственный подклассUIPresentationController
сshouldRemovePresentersView
возвращая ДА.
Я сделал это, и viewFromKey:
не возвращается nil
больше, но теперь контроллер представления полностью исчезает (что имеет смысл, учитывая, что я прямо говорю, что это должно быть реализовано shouldRemovePresentersView
).
Я добавляю представление контроллера представления к представлению контейнера, но оно все равно удаляется. Что-нибудь еще, что я должен сделать, чтобы заставить это работать?
Вот некоторый соответствующий код:
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
BOOL show = self.isPresentation;
UIView *menuView = show ? toView : fromView;
UIView *backView = show ? fromView : toView;
UIView *containerView = [transitionContext containerView];
[containerView addSubview:backView];
[containerView addSubview:dimmedView];
[containerView addSubview:menuView];
// Adjust transforms, alpha and perform animations
Я думал, что, возвращаясь YES
от shouldRemovePresentersView
и вручную добавив его в containerView
, это должно решить проблему, но backView
все равно удаляется...
2 ответа
Я добавляю другой ответ, так как мой ответ слишком длинный, чтобы поместиться в комментарии.
Прежде всего viewForKey
доступен в iOS8, поэтому, если вы не ориентируетесь только на iOS8 (почему?), вы не должны использовать его или проверять, что UIViewControllerContextTransitioning
отвечает на этот селектор и использовать viewControllerForKey
для iOS7.
С учетом сказанного, мне кажется, что это ошибка, и я объясняю себя:
Если вы посмотрите на UIPresentationController
Заголовочный файл, вы увидите, что он говорит
// Indicate whether the view controller's view we are transitioning from will be removed from the window in the end of the
// presentation transition
// (Default: YES)
- (BOOL)shouldRemovePresentersView;
Итак, как вы видите, по умолчанию установлено значение YES, поэтому оно должно быть переопределено, только если вы специально хотите сказать NO. Тем не менее, вы правы, без того, чтобы явно установить YES, viewForKey
для UITransitionContextFromViewControllerKey
остается ноль.
Я думаю, что вы должны заполнить отчет об ошибке для этого и сейчас используйте viewControllerForKey
это хорошо для использования (в этом нет ничего плохого), поскольку оно не устарело и работает в обеих версиях ОС без проблем.
И причина этого, скорее всего, ошибка в том, что viewForKey
должен вернуть представление дляUITransitionContextFromViewControllerKey
когда shouldRemovePresentersView
явно установлен на НЕТ, а не ДА.
Мои 2 цента
Почему вы настраиваете shouldRemovePresentersView
в YES
если вы хотите, чтобы fromView оставался видимым?
У меня была та же проблема, что и у вас, так как в моей пользовательской 3d-презентации родительский контроллер представления был удален, как только переход был завершен.
Решение есть изменить modalPresentationStyle
в UIModalPresentationOverCurrentContext
Это будет специально запрещать системе удалять владельца viewController после завершения перехода.
Тем не менее, мой 3D-переход страдал от проблем с анимацией при использовании этого подхода.
Si я в конечном итоге с помощью UIModalPresentationCustom
modalPresentationStyle
это решило почти все мои проблемы, за исключением того, что новый контроллер представления (который был UINavigationController) не будет перемещаться вниз, когда появится строка состояния в вызове.
Чтобы решить эту проблему, я изменил modalPresentationStyle
вернуться к UIModalPresentationFullScreen
после того, как переход был завершен.
Вот мой код, который показывает новый viewController с пользовательской презентацией:
//show Login Screen
LoginViewController *viewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];
UINavigationController *loginNavController = [[UINavigationController alloc] initWithRootViewController:viewController];
loginNavController.interactivePopGestureRecognizer.enabled = YES;
loginNavController.transitioningDelegate = self.customTransitionDelegate;
loginNavController.modalPresentationStyle = UIModalPresentationCustom;
[navigationController presentViewController:loginNavController animated:YES
completion:^{
//important, else status bar is not moving entire screen down....
loginNavController.modalPresentationStyle = UIModalPresentationFullScreen;
}
];
Также очень важно, что вы не должны добавлять старый вид к containerView
когда вы запускаете анимацию увольнения
Так что, если анимация представляет, добавьте toView
к containerView
UIView* inView = [transitionContext containerView];
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
.....
......
[inView insertSubview:toViewController.view aboveSubview:fromViewController.view];
Но на презентации об увольнении НЕ ДОБАВЛЯЙТЕ вид на containerView
как он все еще показывает (поскольку мы специально попросили систему НЕ удалять его), а просто анимируем между двумя представлениями.