如何将 UIImage 添加到分组的 UITableViewCell 中,使其圆角?

发布于 2024-08-18 15:24:55 字数 129 浏览 6 评论 0原文

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

例如,表格中的第一个图像只需将左上角圆角化。

I'm trying to add images to table cells in a grouped UITableView but the corners of the images are not clipped. What's the best way to go about clipping these (besides clipping them in Photoshop? The table contents are dynamic.)

For example, the first image in a table would need the top left corner rounded only.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小嗲 2024-08-25 15:24:55

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

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

This was my solution, which could use a little refactoring:

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

Implement those functions, then check the indexPath in the cellForRowAtIndexPath delegate method to determine which corner to round.

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;
        }
紫轩蝶泪 2024-08-25 15:24:55

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

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

如果您还想从边界插入图像,我描述了 UIImage 上的简单类别可在此处执行此操作

If you're happy to have all four image corners rounded, then you can just do the following when creating the cell:

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

If you also want to inset the image from the boundary, I described a simple category on UIImage to do it here.

空‖城人不在 2024-08-25 15:24:55

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

There isn't a built-in standard way to do this, but it's not terribly hard to do in your own code. There are examples on how to round corners on an UIImage on the web, see for example http://blog.sallarp.com/iphone-uiimage-round-corners/.

鹊巢 2024-08-25 15:24:55

如果您只想显示圆角,可以使用内置方法。将图像放入UIImageView中,然后设置UIImageView所在图层的cornerRadius。您还需要告诉 UIImageView 剪裁到边界,但这会给您带来圆角。

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

There is built-i way if you want to just display the rounded corners. Put the image in a UIImageView and then set the cornerRadius of the layer of the UIImageView. You will also need to tell the UIImageView to clip to bounds but that will give you rounded corners.

UIImageView *myImageView = [[UIImageView alloc] initWithImage:...];
[myImageView setClipsToBounds:YES];
[[myImageView layer] setCornerRadius:5.0f];
痴情换悲伤 2024-08-25 15:24:55

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

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

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

我应该补充一点,上面的用法片段是在 cellForRowAtIndexPath 方法中使用的,并且“cell”是一个 uitableviewcell。

不管怎样,对我来说就像冠军一样。

A couple additions/changes, hope it helps someone:

1) roundTop and roundBottom impl changed slightly.

2) made a class method in separate class so reuse is easier, rather than copy/paste everywhere.

First, the new class details:

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

@interface RoundedImages : NSObject {
}
+(UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom;
@end

And its implementation:

#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

To use in another class (eg, view controller):

#import "RoundedImages.h"

...and later we use it like this...

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

Note that the "choices" above was just a mutable array I was using on this page that contained the data for the tableview.

I should add that the usage snippet above is used inside your cellForRowAtIndexPath method, and "cell" is a uitableviewcell.

Anyway, works like a champ for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文