present一个半透明的controller

有时候想要实现类似系统的弹窗效果,但是又需要自定义弹窗视图时,往往都会自定义一个view类,放到window上,其实还可以使用自定义一个背景色透明或半透明的controller来实现,这样可以使加载和销毁视图更方便。

那怎样present一个半透明的controller呢?

在当前controller中要present一个半透明的TestViewController:

1
2
3
4
5
TestViewController * testVC = [TestViewController new];
self.definesPresentationContext = YES; //设置当前控制器为present上下文
testVC.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.4];
testVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;//或者UIModalPresentationOverFullScreen 这两个都是全屏效果,其他Style会遮盖当前控制器内容
[self presentViewController:testVC animated:YES completion:nil];

这时,present动画效果是系统默认的自下而上的动画效果,还可以修改动画效果,比如:

在TestViewController中添加动画方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// 视图动画效果,从0到1为显示动画,从1到0为隐藏动画,需要注意动画只是改变了控制器视图的显示和隐藏,还需要配合controller的present和dismiss方法
-(void)animationFrom:(CGFloat)from to:(CGFloat)to
{
CAAnimationGroup *animations = [CAAnimationGroup animation];
CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath: @"opacity"];
animation1.fromValue = @(from);
animation1.toValue = @(to);

CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath: @"contents"];
animation2.fromValue = @(from);
animation2.toValue = @(to);

animations.animations = @[animation2, animation1];
animations.duration = .2f;
animations.removedOnCompletion = NO;
animations.autoreverses = NO;
animations.fillMode = kCAFillModeBoth;
[self.view.layer addAnimation: animations forKey:@"zoom"];
}

在present该controller时调用:

1
2
3
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;//或者UIModalPresentationOverCurrentContext
[self presentViewController:vc animated:NO completion:nil];
[vc animationFrom:0.0 to:1.0];

在dismiss时:

1
2
3
4
[self animationDismiss];
dispatch_after(2.0, dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:NO completion:nil];
});