我想我想要做的事情很简单,但我似乎无法弄明白。我知道如何使用UIImage
在UIImageView
上应用渐变,但这不是我想要的。我想要做的是,在保持图像边界的同时,淡出UIImage
的上半部分,使其完全透明。我希望能够看到UIImage
后面的视图,图像的下半部分仍然完全可见(不透明)。
有什么想法吗?任何帮助将不胜感激。
答案 0 :(得分: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)
不要忘记从图像子图层中删除子图层非常重要,否则单元格将具有多于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;
}
答案 2 :(得分: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];
}
});
希望有所帮助!
答案 3 :(得分: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