使用自定义转换旋转模态 UIViewController
Rotating a modal UIViewController with custom transition
我有一个自定义的 UIViewController 类别,它应用了一个模糊父级并将其向后和向上推的过渡。
看起来像这样:
我正在 animateTransition
中创建父级的模糊屏幕截图,将其与 obj_setAssociatedObject
关联到呈现的 viewcontroller 并在关闭后将其删除。
它就像一个魅力,但是当我旋转到横向时,背景视图不会旋转,这是预期的:
我尝试在 animateTransition
中添加方向更改的通知,但由于它位于转换管理器的内部,它将在转换完成后被释放(我假设)。
尝试将转换管理器对象关联到呈现的 VC,但没有成功。
当方向发生变化时,如何从过渡管理器内部或结合父类别更新模糊视图? ( iOS 7 兼容 )
类别:
- (void)presentCustom:(UIViewController *)viewControllerToPresent
completion:(void (^)(void))completion
{
viewControllerToPresent.transitioningDelegate = self;
[self presentViewController:viewControllerToPresent animated:YES completion:completion];
}
- (void)dismissCustom:(void (^)(void))completion
{
[self dismissViewControllerAnimated:YES completion:completion];
}
所以我确实想出了以下方法,它似乎有效,可能对遇到这种情况的人有所帮助。
//#import "NSObject+AssociatedObjects.h"
// in animateTransition , presenting part
// adds self to the presented controller
[toViewController associateValue:self withKey:&kTransitionManagerAssocKey];
// adds sourceVS to self
[self associateValue:fromViewController withKey:&kOriginalViewControllerAssocKey];
// adds the blurred image to presentedVC
[toViewController associateValue:blurImageView withKey:&kBlurImageAssocKey];
// adds presentedVC to self
[self associateValue:toViewController withKey:&kPresentedViewControllerAssocKey];
// Register for orientation changes, so we can update the presenting controller screenshot
// in the method get the original controller, render it in the existing blurred view or replace it and readd it to the container
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(transitionManager_interfaceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
对于解散部分,所有内容都需要清理:
// get the associated manager and clear everything
TransitionManager * oldManager = [fromViewController associatedValueForKey:&kTransitionManagerAssocKey];
if (oldManager)
{
[[NSNotificationCenter defaultCenter] removeObserver:oldManager name:UIDeviceOrientationDidChangeNotification object:nil];
[oldManager associateValue:nil withKey:&kOriginalViewControllerAssocKey];
[oldManager associateValue:nil withKey:&kPresentedViewControllerAssocKey];
[fromViewController associateValue:nil withKey:&kTransitionManagerAssocKey];
}
// this one is cleared when the transition is complete
[fromViewController associateValue:nil withKey:&kBlurImageAssocKey];
我有一个自定义的 UIViewController 类别,它应用了一个模糊父级并将其向后和向上推的过渡。
看起来像这样:
我正在 animateTransition
中创建父级的模糊屏幕截图,将其与 obj_setAssociatedObject
关联到呈现的 viewcontroller 并在关闭后将其删除。
它就像一个魅力,但是当我旋转到横向时,背景视图不会旋转,这是预期的:
我尝试在 animateTransition
中添加方向更改的通知,但由于它位于转换管理器的内部,它将在转换完成后被释放(我假设)。
尝试将转换管理器对象关联到呈现的 VC,但没有成功。
当方向发生变化时,如何从过渡管理器内部或结合父类别更新模糊视图? ( iOS 7 兼容 )
类别:
- (void)presentCustom:(UIViewController *)viewControllerToPresent
completion:(void (^)(void))completion
{
viewControllerToPresent.transitioningDelegate = self;
[self presentViewController:viewControllerToPresent animated:YES completion:completion];
}
- (void)dismissCustom:(void (^)(void))completion
{
[self dismissViewControllerAnimated:YES completion:completion];
}
所以我确实想出了以下方法,它似乎有效,可能对遇到这种情况的人有所帮助。
//#import "NSObject+AssociatedObjects.h"
// in animateTransition , presenting part
// adds self to the presented controller
[toViewController associateValue:self withKey:&kTransitionManagerAssocKey];
// adds sourceVS to self
[self associateValue:fromViewController withKey:&kOriginalViewControllerAssocKey];
// adds the blurred image to presentedVC
[toViewController associateValue:blurImageView withKey:&kBlurImageAssocKey];
// adds presentedVC to self
[self associateValue:toViewController withKey:&kPresentedViewControllerAssocKey];
// Register for orientation changes, so we can update the presenting controller screenshot
// in the method get the original controller, render it in the existing blurred view or replace it and readd it to the container
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(transitionManager_interfaceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
对于解散部分,所有内容都需要清理:
// get the associated manager and clear everything
TransitionManager * oldManager = [fromViewController associatedValueForKey:&kTransitionManagerAssocKey];
if (oldManager)
{
[[NSNotificationCenter defaultCenter] removeObserver:oldManager name:UIDeviceOrientationDidChangeNotification object:nil];
[oldManager associateValue:nil withKey:&kOriginalViewControllerAssocKey];
[oldManager associateValue:nil withKey:&kPresentedViewControllerAssocKey];
[fromViewController associateValue:nil withKey:&kTransitionManagerAssocKey];
}
// this one is cleared when the transition is complete
[fromViewController associateValue:nil withKey:&kBlurImageAssocKey];