【问题标题】:Unable to add shadow to UIImage in UITableViewCell无法在 UITableViewCell 中为 UIImage 添加阴影
【发布时间】:2011-12-26 16:06:23
【问题描述】:

我有一个 UITableViewCell 正在drawContentView: 中绘制图像我想给它添加一个阴影,所以我正在使用 CALayers:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    AsyncCell *cell = (AsyncCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[AsyncCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    NSDictionary* obj = [facebookPhotosData objectAtIndex:indexPath.row];
    [cell updateCellInfo:obj];

    CALayer *sublayer = [CALayer layer];
    sublayer.contents = (id)cell.image.CGImage;
    sublayer.shadowOffset = CGSizeMake(0, 3);
    sublayer.shadowRadius = 5.0;
    sublayer.shadowColor = [UIColor blackColor].CGColor;
    sublayer.shadowOpacity = 0.8;
    sublayer.frame = CGRectMake(5.0, 5.0, cell.image.size.width, cell.image.size.height);
    [cell.layer addSublayer:sublayer];

    return cell;
}

这是我的 drawContentView 方法,如果我在这里添加子图层,它们会不断堆叠:

- (void) drawContentView:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor whiteColor] set];
    CGContextFillRect(context, rect);

    NSString* caption = [NSString stringWithFormat:@"%@",[info objectForKey:@"caption"]];
    NSString* text = [info stringForKey:@"text"];

    CGFloat widthr = self.frame.size.width - 70;

    [[UIColor grayColor] set];
    [text drawInRect:CGRectMake(63.0, 25.0, widthr, 20.0) withFont:system14 lineBreakMode:UILineBreakModeTailTruncation];

    if (self.image) {
        UIImage *imageToDisplay;
        imageToDisplay = self.image;
        imageToDisplay = [self imageWithImage:imageToDisplay scaledToSize:CGSizeMake(imageToDisplay.size.width / 1.5, imageToDisplay.size.height / 1.5)];
        CGFloat width;
        CGFloat height;
        CGRect r;
        if (imageToDisplay.size.width < 310 && imageToDisplay.size.height > 290) {
            imageToDisplay = [self imageByCropping:imageToDisplay toRect:CGRectMake(0, 20, imageToDisplay.size.width, 250)];

        }
        else if (imageToDisplay.size.width > 310 && imageToDisplay.size.height < 20) {
            imageToDisplay = [self imageByCropping:imageToDisplay toRect:CGRectMake(30, 0, 290, 250)];
        }
        else {
            imageToDisplay = [self imageByCropping:imageToDisplay toRect:CGRectMake(30, 0, 290, 250)];

        }

        width = imageToDisplay.size.width;
        height = imageToDisplay.size.height;
        r = CGRectMake(5.0, 5.0, width, height);

        [imageToDisplay drawInRect:r];

        CALayer *sublayer = [CALayer layer];
        sublayer.contents = (id)imageToDisplay.CGImage;
        sublayer.shadowOffset = CGSizeMake(0, 3);
        sublayer.shadowRadius = 5.0;
        sublayer.shadowColor = [UIColor blackColor].CGColor;
        sublayer.shadowOpacity = 0.8;
        sublayer.frame = CGRectMake(5.0, 5.0, imageToDisplay.size.width, imageToDisplay.size.height);
        [self.layer addSublayer:sublayer];


        //Experimental shadow stuff with images
        /*CALayer *layer = [CALayer layer];
        layer = [CALayer layer];
        layer.bounds = CGRectMake(5.0, 5.0, imageToDisplay.size.width, imageToDisplay.size.height);
        layer.position = CGPointMake(150, 140);
        layer.contents = (id)imageToDisplay.CGImage;    

        layer.shadowOffset = CGSizeMake(0, 2);
        layer.shadowOpacity = 0.70;

        [self.layer addSublayer:layer];

        [self bezierPathWithCurvedShadowForRect:layer.bounds];*/

        [[UIColor blackColor] set];
        [caption drawInRect:CGRectMake(0, 270 , 298, 20.0) withFont:system14 lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter];
    }
}

当我将代码放入此委托方法时,什么也没有发生。如果我将它添加到 drawContentView 中,它会绘制阴影,但在滚动时不断添加图层,这是不正确的。不确定如何为图像添加阴影?

【问题讨论】:

    标签: iphone objective-c cocoa-touch uitableview calayer


    【解决方案1】:

    根据提供的描述,我并不清楚 drawContentView 方法中有什么以及何时调用它,但是您给出的代码“在滚动时不断添加图层”的原因是它确实将您的子图层添加到每次调用 tableView:cellForRowAtIndexPath: 的单元格(滚动时经常发生这种情况)

    因此,第一个明显的解决方法如下:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *CellIdentifier = @"Cell";
    
         AsyncCell *cell = (AsyncCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[AsyncCell alloc] initWithStyle:UITableViewCellStyleDefault                 reuseIdentifier:CellIdentifier];
            CALayer *sublayer = [CALayer layer];
            sublayer.contents = (id)cell.image.CGImage;
            sublayer.shadowOffset = CGSizeMake(0, 3);
            sublayer.shadowRadius = 5.0;
            sublayer.shadowColor = [UIColor blackColor].CGColor;
            sublayer.shadowOpacity = 0.8;
            sublayer.frame = CGRectMake(5.0, 5.0, cell.image.size.width, cell.image.size.height);
            [cell.layer addSublayer:sublayer];
        }
    
        NSDictionary* obj = [facebookPhotosData objectAtIndex:indexPath.row];
        [cell updateCellInfo:obj];
    
        return cell;
    }
    

    因此您只需要绘制一次阴影,可能是在创建单元格时。 就我个人而言,我宁愿在 AsyncCell 类中有这段代码。 希望这会有所帮助。

    【讨论】:

    • 我得到相同的结果,阴影没有出现。当我把它放在 drawContentView 中时,它会被多次添加。更新了原始问题。
    • drawContentView 在哪里调用?
    • 你有什么理由使用 drawInRect 而不仅仅是设置 cell.textLabel.text 属性?这是为了在滚动时加快速度吗?
    • 你在drawRect中调用drawContentView方法吗?
    【解决方案2】:

    哦,现在我知道发生了什么。尝试将所有代码从 drawContentView: 移动到 drawRect: 方法。这应该可以解决问题,因为 drawRect 方法仅在设置 setNeedsDisplay 标志时调用,而不是每次用户滚动时调用。

    【讨论】:

      猜你喜欢
      • 2021-10-07
      • 2021-11-06
      • 2011-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 2011-02-25
      相关资源
      最近更新 更多