您的位置:首页 > 产品设计 > UI/UE

iOS8新特性——UIPresentation在转场动画中的使用

2016-05-13 11:18 701 查看
iOS8中苹果给我们来带来了一个新的类——
UIPresentationController
。和
UIViewControllerTransitioning
一样,它也是配合自定义过渡的。在实践中,往往也是配合
UIViewControllerTransitioning
一起来实现自定义的转场动画。今天我们要实现的一个转场是这样的:



我们的
UIPresentationController
的子类是负责「被呈现」(presented) 及「负责呈现」(presenting) 的
controller 以外的 controller 的,看着很绕口,说白了,在我们的例子中,它负责的仅仅是那个带渐变效果的黑色模糊背景 View和背景视图的动态缩放。

UIPresentationController.h
的内容其实不多,也就80行代码。其中我们我们必须实现的有这四个方法:
- (void)presentationTransitionWillBegin;////在呈现过渡即将开始的时候被调用的

- (void)presentationTransitionDidEnd:(BOOL)completed;////在呈现过渡结束时被调用的

- (void)dismissalTransitionWillBegin;//在退出过渡即将开始的时候被调用的

- (void)dismissalTransitionDidEnd:(BOOL)completed;//在退出的过渡结束时被调用的


按照上面gif显示的效果,我们可以在
- (void)presentationTransitionWillBegin;
中做如下操作:
- (void)presentationTransitionWillBegin{

//创建视图
self.bgView = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
self.blurView = [[UIVisualEffectView alloc]initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
self.blurView.frame = self.containerView.bounds;
[self.bgView insertSubview:self.blurView atIndex:0];

self.contview = self.containerView;
[self.contview addSubview:self.presentingViewController.view];
[self.contview addSubview:self.bgView];
[self.contview addSubview:self.presentedView];

// 使用 presentingViewController 的 transitionCoordinator,
// 背景 bgView 的淡入效果与过渡效果一起执行
self.bgView.alpha = 0.0;
self.transitionCoordinator = self.presentingViewController.transitionCoordinator;
[self.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
self.bgView.alpha = 0.7;
self.presentingViewController.view.transform = CGAffineTransformScale(self.presentingViewController.view.transform, 0.92, 0.92);
} completion:nil];
}


还是比较容易看懂的。无非就是就是新建了一个背景,上面加一个
UIVisualEffectView
的带模糊效果的视图。然后让背景的alpha从0变到1。同时我们还做了让底下那个视图x、y都缩放到原来的0.92倍。

如果没有完成,移除视图。
//在呈现过渡结束时被调用的
//如果呈现没有完成,那就移除背景 View
- (void)presentationTransitionDidEnd:(BOOL)completed{
if (!completed) {
[self.bgView removeFromSuperview];

}
}


同理,
dismissalTransitionWillBegin
方法中,我们把背景层的透明度恢复到0.同时也让底下的视图恢复transform.
- (void)dismissalTransitionWillBegin{
// 与过渡效果一起执行背景 View 的淡出效果
self.transitionCoordinator = self.presentingViewController.transitionCoordinator;
[self.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
self.bgView.alpha = 0;
self.presentingViewController.view.transform = CGAffineTransformIdentity;
} completion:nil];
}


最后,成功完成dismiss之后移除视图。
- (void)dismissalTransitionDidEnd:(BOOL)completed{
if (completed) {
[self.bgView removeFromSuperview];
}

[[[UIApplication sharedApplication]keyWindow]addSubview:self.presentingViewController.view];
}


这里要说明一点的是,如果没有
[[[UIApplication sharedApplication]keyWindow]addSubview:self.presentingViewController.view];
这一句的话,dismiss结束之后背景会变黑,原因是
presentingViewController
随着
self.containerView
被一同销毁了。我在Stackoverflow终于找到了答案,据说是iOS8的bug,同时解决方案是在window上重新添加一下,也就是
[[[UIApplication
sharedApplication]keyWindow]addSubview:self.presentingViewController.view];
.

使用方式和前三篇博文提到的
UIViewControllerTransitioning
一样,在presented的ViewController中实现
UIViewControllerTransitioningDelegate
协议,并且重载下面这个方法就可以了:
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator{

if (animator) {
return percentDrivenInteractiveTransition;
}else{
return nil;
}
}


老规矩,全部代码已开源(这里),供学习参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: