具有多个alpha值的矩形CALayer蒙版

时间:2017-04-05 17:41:29

标签: ios objective-c calayer mask

我试图通过屏蔽UITableView的顶部来给出导航栏的错觉。顶部应具有50%的不透明度,而视图的其余部分应具有100%的不透明度。

使用CAGradientLayer非常容易,例如:

- (void)addTopOpacityMask
{
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = self.tableView.frame;

    id transparent = (id)[UIColor clearColor].CGColor;
    id opaque = (id)[UIColor blackColor].CGColor;
    gradientLayer.colors = @[transparent, opaque, opaque];
    gradientLayer.locations = @[@0.1, @0.11, @1];
    self.tableView.superview.layer.mask = gradientLayer;
}

但据我所知,locations属性中的每个值都必须是唯一的,因此总会有一个小的渐变(我不想要)。将位置设置为

@[@0.1, 0.10001, @1];

看起来像一个非常不合时宜的解决方案,因为您还需要将所述蒙版的高度转换为位置。

我考虑过使用CAShapeLayer并简单地创建顶部作为掩码,请参阅下面的代码,但这显然会切掉表视图的其余部分,因为掩码只覆盖顶部。

- (void)addTopOpacityMask
{
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.fillRule = kCAFillRuleEvenOdd;
    shapeLayer.fillColor = [UIColor blackColor].CGColor;
    shapeLayer.opacity = 0.5;
    CGRect maskRect = CGRectMake(0, 0, CGRectGetWidth(self.tableView.frame), 76);

    CGPathRef path = CGPathCreateWithRect(maskRect, NULL);
    shapeLayer.path = path;
    CGPathRelease(path);

    self.tableView.superview.layer.mask = shapeLayer;
}

我错过了什么?

我想掩盖它而不是仅仅在表格视图顶部添加50%透明视图的原因很简单。表格视图也具有透明背景,我只希望导航栏在用户开始滚动时突出显示(类似于雅虎天气应用程序的工作原理/用于工作)。

修改

澄清一下,这是默认情况下的样子(注意你看不到导航栏):

enter image description here

这就是当您在表格视图中向下滚动时的样子(表视图的alpha被截断,但我们不会更改视图的背景颜色,这是半透明的):

enter image description here

1 个答案:

答案 0 :(得分:0)

再次编辑:好的......再试一次 - 这可能适合你。玩了一下......似乎得到了你想要的效果,面具的半透明部分需要一个非常低的不透明度值。无论如何,这段代码:

- (void)addTopOpacityMask {

    CGRect rect = _tableView.frame;
    CGRect r = rect;

    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    // fill a "top rect" with black at 5% opacity
    r.size.height = 76;

    CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:0.0 alpha:0.05].CGColor);
    CGContextFillRect(context, r);

    // fill the rest of the layer with black at 100% opacity
    r.origin.y = 76;
    r.size.height = rect.size.height;

    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillRect(context, r);

    // grab a UIImage from the context
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // create a Layer
    CALayer *theLayer = [CALayer layer];

    // set the Layer content to the just-created image
    theLayer.contents = (__bridge id _Nullable)(image.CGImage);

    theLayer.frame = rect;

    // mask the view holding the tableview
    _tableView.superview.layer.mask = theLayer;

}

给了我这个结果:

enter image description here

enter image description here

编辑:不确定我是否看到了您所看到的内容......但是,您是否尝试过这样做?

- (void)addTopOpacityMask
{
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = self.tableView.frame;

    id transparent = (id)[UIColor clearColor].CGColor;
    id opaque = (id)[UIColor blackColor].CGColor;

    // use 4 color slots
    gradientLayer.colors = @[transparent, transparent, opaque, opaque];

    // and 4 color locations (I don't get an error when using 2 of the same values)
    gradientLayer.locations = @[@0.1, @0.11, @0.11, @1];

    self.tableView.superview.layer.mask = gradientLayer;
}

可以简单地创建一个CALayer并给它一个半透明的背景色......这样的事情:

CALayer *theLayer = [CALayer alloc];
CGRect r = tableView.bounds;
r.size.height = 76.0;
theLayer.frame = r;
theLayer.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5].CGColor;
[tableView.superview.layer addSublayer:theLayer];