UIImageView上的透明度渐变

6
我想我要做的事情很简单,但我似乎无法弄清楚。我知道如何使用UIImageViewUIImage上应用渐变,但那不是我想要的。我想做的是,在保持图像边界的同时,淡化UIImage的顶部一半,使其完全透明。我希望能够看到UIImage后面的视图,并且图像的底半部仍然完全可见(不是不透明的)。
有任何想法吗?非常感谢您的任何帮助。
4个回答

11

最简单的方法是使用CAGradientLayer作为图层蒙版。换句话说,使用它的不透明度来确定所附加到的图层的不透明度。如下所示即可:

CALayer *imageViewLayer = theImageView.layer;
CAGradientLayer *maskLayer = [CAGradientLayer layer];
maskLayer.colors = @[ (id)([UIColor blackColor].CGColor), (id)([UIColor clearColor].CGColor) ]; // gradient from 100% opacity to 0% opacity (non-alpha components of the color are ignored)
// startPoint and endPoint (used to position/size the gradient) are in a coordinate space from the top left to bottom right of the layer: (0,0)–(1,1)
maskLayer.startPoint = CGPointMake(0, 0.5); // middle left
maskLayer.endPoint = CGPointMake(0, 0); // top left
maskLayer.frame = imageViewLayer.bounds; // line it up with the layer it’s masking
imageViewLayer.mask = maskLayer;

谢谢,我尝试过了,但我想直接使用UIImages进行操作,你有什么指导吗? - thunderousNinja
为什么?如果您需要调整图像本身,您将不得不通过核心图形进行操作,但这是最直接的方法。 - Noah Witherspoon

2
Swift 5.0(和4.2)版本中诺亚的答案
let maskLayer = CAGradientLayer(layer: theImageView.layer)
maskLayer.colors = [UIColor.black.cgColor, UIColor.clear.cgColor]
maskLayer.startPoint = CGPoint(x: 0, y: 0.5)
maskLayer.endPoint = CGPoint(x: 0, y: 0)
maskLayer.frame = theImageView.bounds
theImageView.layer.mask = maskLayer

1
非常重要的是不要忘记从图像子层中删除子层,否则单元格将具有多个子层,并且将被颜色而不是渐变填充。我尝试在awakeFromNib上执行此操作,但效果不佳-当调用awakeFromNib时,容器宽度未知,因此您可能会获得非全宽度的渐变。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"actionsTableCell";

    actionsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier forIndexPath:indexPath];
    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = cell.myImage.bounds;
    gradient.colors = @[(id)[[UIColor clearColor] CGColor],
                    (id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor],
                    (id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:1] CGColor]];
    [[cell.myImage.layer.sublayers objectAtIndex:0] removeFromSuperlayer];
    [cell.myImage.layer addSublayer:gradient];

    cell.header.text = [recipes objectAtIndex:indexPath.row];
    return cell;
}

0
尝试对下面Noah的代码进行以下修改。实际上,枚举检查是否定义了蒙版层,而不是使用默认的layer.mask CALayer。我在UIImageView中设置这个值时遇到了一个有趣的问题。
    CALayer *_layerImage = _imageViewBackground.layer;
    CGRect _rect = _imageViewBackground.bounds;

    __block CAGradientLayer *_maskLayer = nil;

    [_layerImage.sublayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj isKindOfClass:[CAGradientLayer class]]) {
            _maskLayer = (CAGradientLayer*) obj;
            *stop = YES;
        }
    }];

    BOOL _found = YES;
    if (!_maskLayer) {
        _maskLayer = [CAGradientLayer layer];
        _found = NO;
    }

    _maskLayer.colors = @[ (id)([UIColor redColor].CGColor), (id)([UIColor clearColor].CGColor) ]; // gradient from 100% opacity to 0% opacity (non-alpha components of the color are ignored)
    // startPoint and endPoint (used to position/size the gradient) are in a coordinate space from the top left to bottom right of the layer: (0,0)–(1,1)
    _maskLayer.startPoint = CGPointMake(0, 0);
    _maskLayer.endPoint = CGPointMake(1, 1);
    _maskLayer.frame = _rect; // line it up with the layer it’s masking

    dispatch_async(dispatch_get_main_queue(), ^{
        if (!_found) {
            [_layerImage addSublayer:_maskLayer];
        }
    });

希望这能有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接