轻松实现部分背景半透明的呈现效果

Posted 颐和园

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了轻松实现部分背景半透明的呈现效果相关的知识,希望对你有一定的参考价值。

实现一个简单的呈现/解散动画效果,当呈现时,呈现的主要内容和背景要明显区分,背景呈现一个半透明遮罩效果,透过背景可以看到下层 View Controller 的内容:

呈现控制器(Presenting View Controller)

呈现控制器即要弹出另外一个控制器的 View Controller。本例中即 ViewController 类。当呈现时,使用如下代码:

// 1
UIStoryboard* sb=[UIStoryboard storyboardWithName:@"Main" bundle:nil];
ModalController* vc = [sb instantiateViewControllerWithIdentifier:@"modal"];

// 2
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
// 3
[self presentViewController:vc animated:NO completion:^{
    [vc present];
}];

代码说明:

  1. 呈现时,构造被呈现控制器(Presented View Controller)实例,本例中的被呈现控制器即 ModalController 类。
  2. 将被呈现控制器的 modalPresentationStyle 设置为 OverCurrentContext。这点很重要。
  3. 呈现控制器调用 presentViewController 方法,但 animated 参数要设置为 NO。否则会采用默认的 Transition 动画。这样动画结束后,被呈现控制器的背景色仍然不能呈现透明(或半透明)效果。在完成块中,调用 modalPresentationStyle 的 present 方法,这个方法会播放我们自定义的呈现动画(后面介绍)。

被呈现控制器(Presented View Controller)

首先,在 ModalController.m 中,找到 viewDidLoad 方法加入:

self.view.backgroundColor = [UIColor clearColor];

这是让背景一开始时透明,不然在呈现动画之前会出现一个短暂的白屏(零点几秒,不注意看不见)。

然后是实现 present 方法:

-(void)present{
    //1
    CGFloat originY = self.contentViewCenterY.constant;
    //2
    CGFloat viewHeight = self.view.bounds.size.height;
    // 3
    self.contentViewCenterY.constant = -(viewHeight);
    // 4
    [self.view layoutIfNeeded];
    // 5
    [UIView animateWithDuration:0.5 animations:^{
        // 将背景设置为半透明
        self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.4];
        // 再将 contentView 移入视图
        self.contentViewCenterY.constant = originY;
        [self.view layoutIfNeeded];
    }];
}

这个方法实现呈现动画。代码解释如下:

  1. contentView 是呈现内容的主要View,即呈现后不透明的内容(前景),此外的区域则是半透明的,作为背景显示。而 contentViewCenterY 是一个 IBOutlet 连接,引用了 contentView 的中心 Y 坐标这个约束(通过 IB 创建的),稍后我们会移动这个 Y 坐标的 contant 值,因此需要把原来的 contant 值保存一个备份,以便恢复。
  2. 获取根视图的高度。
  3. 修改 contentViewCenterY 的 contant 值,先将 contentView 移出视图(下方)。
  4. 每次修改约束之后,都要调用 layoutIfNeeded,使约束生效。
  5. 执行 UIView 动画,在动画块中,将背景设置为半透明(原来我们设置为透明了),这个属性不可以动画,因此一旦设置完就不会改变了。然后通过修改 contentViewCenterY 让 我们要呈现的主要内容视图上移到原来的位置(屏幕中心)。最后别忘了修改约束之后要调用 layoutIfNeeded。

然后实现解散动画:

-(void)dismiss{
    // 1
    CGFloat viewHeight = self.view.bounds.size.height;
    // 2
   [UIView animateWithDuration:0.5 animations:^{
       self.contentViewCenterY.constant = -(viewHeight);
       [self.view layoutIfNeeded];
   } completion:^(BOOL finished) {
       [self dismissViewControllerAnimated:NO completion:nil];
   }];
}

解散动画很简单:

  1. 首先获取根视图高度。
  2. 执行 UIView 动画,在动画块中,修改 contentViewCenterY 将我们要呈现的主要内容移除屏幕(下方),别忘了调用 layoutIfNeeded。

然后在关闭按钮或者背景 View 被触摸时调用 dismiss 播放解散动画:

- (IBAction)touched:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

以上是关于轻松实现部分背景半透明的呈现效果的主要内容,如果未能解决你的问题,请参考以下文章

如何让图片以半透明的效果显示在所有程序或窗口的最上层?

easyui实现背景图片半透明状态,悬浮在大背景之上

如何在 iOS 中呈现一个半透明(半切)的视图控制器?

Konva/Canvas 背景模糊/磨砂玻璃效果

unity部分模型半透明了怎么办

Qt实现窗口半透明显示