UIImageView上的透明度渐变

问题描述 投票:6回答:4

我想我想要做的事情很简单,但我似乎无法弄明白。我知道如何使用UIImageUIImageView上应用渐变,但这不是我想要的。我想要做的是,在保持图像边界的同时,淡出UIImage的上半部分,使其完全透明。我希望能够看到UIImage背后的视图,图像的下半部分仍然完全可见(不透明)。

有任何想法吗?任何帮助将不胜感激。

objective-c uiimageview uiimage
4个回答
11
投票

最简单的方法是使用CAGradientLayer作为layer mask - 换句话说,使用其不透明度来确定它所附着的图层的不透明度。这些方面的东西应该可以解决问题:

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;

1
投票

不要忘记从图像子图层中删除子图层非常重要,否则单元格将具有多于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
投票

请尝试以下对诺亚代码的修改。实际上,枚举检查是否存在已定义的遮罩层,而不是使用默认的layer.mask CALayer。我遇到了一个有趣的问题,UIImageViews试图设置这个值。

    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];
        }
    });

希望有所帮助!


0
投票

Swift 5.0(和4.2)版本的Noah's answer

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
© www.soinside.com 2019 - 2024. All rights reserved.