【问题标题】:How do I add a UIImage to grouped UITableViewCell so it rounds the corners?如何将 UIImage 添加到分组的 UITableViewCell 以使其圆角?
【发布时间】:2011-01-08 06:48:54
【问题描述】:

我正在尝试将图像添加到分组 UITableView 中的表格单元格,但图像的角没有被剪裁。剪裁这些的最佳方法是什么(除了在 Photoshop 中剪裁它们?表格内容是动态的。)

例如,表格中的第一张图片只需将左上角圆角即可。

【问题讨论】:

    标签: objective-c iphone-sdk-3.0 uitableview rounded-corners


    【解决方案1】:

    没有内置的标准方法可以做到这一点,但在您自己的代码中做到这一点并不难。网上有一些关于如何在 UIImage 上圆角的示例,请参阅例如 http://blog.sallarp.com/iphone-uiimage-round-corners/

    【讨论】:

    • 嗯。我希望会有一种更内置的标准方式,比如抓取单元格本身的形状掩码。但是,是的——猜不出来。
    【解决方案2】:

    这是我的解决方案,可以使用一些重构:

    void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight, BOOL top, BOOL bottom)
    {
        float fw, fh;
        if (ovalWidth == 0 || ovalHeight == 0) {
            CGContextAddRect(context, rect);
            return;
        }
        CGContextSaveGState(context);
        CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
        CGContextScaleCTM (context, ovalWidth, ovalHeight);
        fw = CGRectGetWidth (rect) / ovalWidth;
        fh = CGRectGetHeight (rect) / ovalHeight;
        CGContextMoveToPoint(context, fw, fh/2);
        CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0);
    
        NSLog(@"bottom? %d", bottom);
    
        if (top) {
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 3);
        } else {
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0);
        }
    
        if (bottom) {
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 3);
        } else {
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0);
        }
    
        CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0);
        CGContextClosePath(context);
        CGContextRestoreGState(context);
    }
    
    - (UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom {
        int w = source.size.width;
        int h = source.size.height;
    
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
    
        CGContextBeginPath(context);
        CGRect rect = CGRectMake(0, 0, w, h);
        addRoundedRectToPath(context, rect, 4, 4, top, bottom);
        CGContextClosePath(context);
        CGContextClip(context);
    
        CGContextDrawImage(context, CGRectMake(0, 0, w, h), source.CGImage);
    
        CGImageRef imageMasked = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
    
        return [UIImage imageWithCGImage:imageMasked];    
    }
    

    实现这些函数,然后检查 cellForRowAtIndexPath 委托方法中的 indexPath 以确定要圆哪个角。

    if (indexPath.row == 0) {
                cell.imageView.image = [self roundCornersOfImage:coverImage roundTop:YES roundBottom:NO];
            } else if (indexPath.row == [indexPath length]) {
                cell.imageView.image = [self roundCornersOfImage:coverImage roundTop:NO roundBottom:YES];
            } else {
                cell.imageView.image = coverImage;
            }
    

    【讨论】:

    • 谢谢,凯文。我已将代码重构为 UIImage 类别,因此我不必到处复制粘贴。
    • 很好的答案,谢谢。一个修复:imageMasked 被泄露。您需要将最终的 UIImage 分配给变量 CGImageRelease(imageMasked) 然后返回 UIImage。
    • .... UIImage *image = [UIImage imageWithCGImage:imageMasked]; CGImageRelease(imageMasked);返回图像; } 谢谢。这就是我要找的。现在可以了。太好了。
    【解决方案3】:

    如果你只想显示圆角,有内置的方法。把图片放在一个 UIImageView 中,然后设置 UIImageView 图层的cornerRadius。您还需要告诉 UIImageView 剪辑到边界,但这会给您圆角。

    UIImageView *myImageView = [[UIImageView alloc] initWithImage:...];
    [myImageView setClipsToBounds:YES];
    [[myImageView layer] setCornerRadius:5.0f];
    

    【讨论】:

    • 好的,所以我注释掉了凯文的解决方案并尝试了这个。首先,我必须添加 QuartzCore 框架—— setCornerRadius 在 QuartzCore 中。不幸的是, setCornerRadius 将所有四个角都舍入了。如果我想匹配一个分组的 UITableViewCell.imageView 的形状,我需要将图像的左上角在顶行上四舍五入——但其他的必须保持清晰。因此,虽然 setCornerRadius 很方便,但它不适合您必须选择要圆角的应用程序。
    【解决方案4】:

    如果您很高兴将所有四个图像角都修圆,那么您可以在创建单元格时执行以下操作:

    cell.imageView.layer.masksToBounds = YES;
    cell.imageView.layer.cornerRadius = 10.0;
    

    如果您还想从边界插入图像,我描述了simple category on UIImage to do it here

    【讨论】:

    • 确保包含 QuartzCore 框架并导入 以使用层属性。
    【解决方案5】:

    一些添加/更改,希望对某人有所帮助:

    1) roundTop 和 roundBottom impl 略有变化。

    2) 在单独的类中创建了一个类方法,因此重用更容易,而不是到处复制/粘贴。

    一、新班级详情:

    #import <Foundation/Foundation.h>
    #import <QuartzCore/QuartzCore.h>
    
    @interface RoundedImages : NSObject {
    }
    +(UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom;
    @end
    

    及其实现:

    #import "RoundedImages.h"
    
    @implementation RoundedImages
    
    void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight, BOOL top, BOOL bottom)
    {
        float fw, fh;
        if (ovalWidth == 0 || ovalHeight == 0) {
            CGContextAddRect(context, rect);
            return;
        }
        CGContextSaveGState(context);
        CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
        CGContextScaleCTM (context, ovalWidth, ovalHeight);
        fw = CGRectGetWidth (rect) / ovalWidth;
        fh = CGRectGetHeight (rect) / ovalHeight;
        CGContextMoveToPoint(context, fw, fh/2);
    
        if (top) {
            CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 3);
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 3);
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0);
            CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0);
        } else {
            CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0);
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0);
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 3);
            CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 3);
        }
    
        CGContextClosePath(context);
        CGContextRestoreGState(context);
    }
    
    +(UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom {
        int w = source.size.width;
        int h = source.size.height;
    
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
    
        CGContextBeginPath(context);
        CGRect rect = CGRectMake(0, 0, w, h);
        //addRoundedRectToPath(context, rect, 4, 4, top, bottom);
        addRoundedRectToPath(context, rect, 5, 5, top, bottom);
        CGContextClosePath(context);
        CGContextClip(context);
    
        CGContextDrawImage(context, CGRectMake(0, 0, w, h), source.CGImage);
    
        CGImageRef imageMasked = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
    
        //return [UIImage imageWithCGImage:imageMasked];
        UIImage *image = [UIImage imageWithCGImage:imageMasked]; 
        CGImageRelease(imageMasked);
        return image;
    }
    
    @end
    

    在另一个类中使用(例如,视图控制器):

    #import "RoundedImages.h"
    

    ...后来我们就这样用了...

    UIImageView *imageView = nil;
        UIImage *img = [UIImage imageNamed:@"panel.png"];
    
        if (indexPath.row == 0) {
            imageView = [[UIImageView alloc]initWithImage:[RoundedImages roundCornersOfImage:img roundTop:YES roundBottom:NO]];
        }
        else if (indexPath.row == ([choices count]-1))
        {
            imageView = [[UIImageView alloc]initWithImage:[RoundedImages roundCornersOfImage:img roundTop:NO roundBottom:YES]];
        }
        else {
            imageView = [[UIImageView alloc]initWithImage:img];
        }
        cell.backgroundColor = [UIColor clearColor];
        imageView.clipsToBounds = NO;
        cell.backgroundView = imageView;
        cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
        [cell.backgroundView addSubview:imageView];
        [imageView release];
    

    请注意,上面的“选择”只是我在此页面上使用的一个可变数组,其中包含 tableview 的数据。

    我应该补充一点,上面的用法 sn-p 是在你的 cellForRowAtIndexPath 方法中使用的,“cell”是一个 uitableviewcell。

    无论如何,对我来说就像一个冠军。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 2022-01-22
    • 2023-03-24
    • 1970-01-01
    • 2010-09-20
    • 2011-05-13
    相关资源
    最近更新 更多