为所有 UIImageViews 添加圆角

Posted

技术标签:

【中文标题】为所有 UIImageViews 添加圆角【英文标题】:Add rounded corners to all UIImageViews 【发布时间】:2011-01-11 09:44:48 【问题描述】:

我想为我项目中的所有 UIImageView 添加一些圆角。我已经让代码工作了,但我必须将它应用到每张图片上;我应该继承 UIImageView 来添加这个吗?如果是这样,有人可以给我一些关于如何做到这一点的指示吗?

这里是代码

- (void)viewDidLoad 
    [super viewDidLoad];
    NSString *mainpath = [[NSBundle mainBundle] bundlePath];
    welcomeImageView.image = [UIImage imageWithContentsOfFile:[mainpath stringByAppendingString:@"/test.png"]];
    welcomeImageView.layer.cornerRadius = 9.0;
    welcomeImageView.layer.masksToBounds = YES;
    welcomeImageView.layer.borderColor = [UIColor blackColor].CGColor;
    welcomeImageView.layer.borderWidth = 3.0;
    CGRect frame = welcomeImageView.frame;
    frame.size.width = 100;
    frame.size.height = 100;
    welcomeImageView.frame = frame;

【问题讨论】:

嗨,杰克 - 谢谢你,这正是我想做的。当我尝试使用它时,我收到一个错误“访问属性的未知 'cornerRadius' 组件”,对于 maskToBounds 等也是如此。奇怪的是,xcode 中的代码感知功能有助于为我填充这些属性,但编译器不会编译它们。上面的代码在 ios4.0 上对你有用吗? 你需要#import 【参考方案1】:

检查这个 - Rounded Corners on UIImage

图层修改似乎是最好的方法。

UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]];
// Get the Layer of any view
CALayer * l = [roundedView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];

【讨论】:

谢谢。这基本上是我已经完成的,但是我使用点符号来更改属性。我只是想知道是否有一个简单的方法是将它添加到子类中,这样如果我想更改半径,我就不必更改它的每个实例。 -1 这并没有试图回答这个问题,即很容易将相同的代码应用于每个UIImageView 实例。【参考方案2】:

您可以为 UIImage 使用一个类别,这是对 Class 进行子类化的另一种方法,有时更容易进行小的更改。

例如添加一个返回带有圆角属性集的 UIImage 的方法。

+(UIImage *)imageWithContentsOfFile:(NSString *)file cornerRadius:(NSInteger)... 

有关 Objective-c 类别的更多信息可以找到http://macdevelopertips.com/objective-c/objective-c-categories.html

【讨论】:

优秀。非常感谢,我将实现一个 UIImage 类别 - macdevelopertips.com 上的教程非常有帮助。 我打算描述如何子类化,但我更喜欢这种方法。 我很困惑。所以 100% 的 UIImages 都会有这个。为什么不继承 UIImage,比如 UIFramedImage? 这里是上述方法的链接igframework-iphone-static-library-project.googlecode.com/… @Rob 实际上,使用这种方法 0% 的 UIImage 将具有圆角,直到您更改它们以调用新方法。此解决方案不会覆盖现有方法(您不应该这样做)。这可能是比子类化更简洁的解决方案,因为它不需要完整的子类——这可能是多余的,因为你没有向 UIImage 添加任何成员或新功能——你想要的只是一个没有代码重复的 UIImage 圆角。 【参考方案3】:

可以通过UIImageView和CALayer上的简单分类实现更强大的功能,而不是子类化。

像这样在 UIImageView 上创建一个类别:

- (void)maskRoundCorners:(UIRectCorner)corners radius:(CGFloat)radius 
    // To round all corners, we can just set the radius on the layer
    if ( corners == UIRectCornerAllCorners ) 
        self.layer.cornerRadius = radius;
        self.layer.masksToBounds = YES;
     else 
        // If we want to choose which corners we want to mask then
        // it is necessary to create a mask layer.
        self.layer.mask = [CALayer maskLayerWithCorners:corners radii:CGSizeMake(radius, radius) frame:self.bounds];
    

这会调用CALayer上的一个分类方法:

+ (id)maskLayerWithCorners:(UIRectCorner)corners radii:(CGSize)radii frame:(CGRect)frame 

    // Create a CAShapeLayer
    CAShapeLayer *mask = [CAShapeLayer layer];

    // Set the frame
    mask.frame = frame;

    // Set the CGPath from a UIBezierPath
    mask.path = [UIBezierPath bezierPathWithRoundedRect:mask.bounds byRoundingCorners:corners cornerRadii:radii].CGPath;

    // Set the fill color
    mask.fillColor = [UIColor whiteColor].CGColor;

    return mask;

因此,这允许您对角的任意组合(请参阅UIRectCorner)进行圆角处理,如果您想将图像置于组样式UITableView 中,这将特别方便。但是,这样做有一个警告。因为我们没有子类化UIImageView,所以我们不能将任何代码注入layoutSubviews,这意味着掩码层可能不正确。实际上,在配置单元格时,调用 category 方法时甚至不会设置图像视图的边界。因此,您需要确保在添加圆角之前设置图像视图的边界(除非使用UIRectCornersAllCorners)。

这里有一些代码可以做到这一点:

        // Perform corner rounding
        UIRectCorner corners = !UIRectCornerAllCorners;
        if (indexPath.row == 0) 
            corners = UIRectCornerTopLeft;
        if (indexPath.row == numberOfRowsInTheTable)  
            corners |= UIRectCornerBottomLeft;

        if (corners > 0) 
            cell.imageView.bounds = CGRectMake(0.f, 0.f, [self.tableView rowHeight], [self.tableView rowHeight]);
            [cell.imageView maskRoundCorners:corners radius:10.f];
         else 
            [cell.imageView removeRoundCornersMask];
        

我还有另一个类别可以去除圆角 - 所做的只是去除所有遮罩并将 cornerRadius 设置为 0。

【讨论】:

很好的解决方案。但我想知道创建所有视图都可以访问它的类是否会更好,例如 UILabel、UIButton、UIView 等 - 一种通用方法? 没关系。我刚刚创建了处理各种视图的 UIView 类别。谢谢! @BorutTomazin 好主意 - 我在想 YAGNI,但是将 UIImageView 类别移动到 UIView 将是一个很棒的小实用功能。 正是我所做的。现在它可以用于其父级为 UIView 的所有视图...【参考方案4】:

是的,您应该继承 UIImageView,并在整个项目中使用您的自定义子类。

【讨论】:

谢谢,我认为这是最好的方法。你知道任何关于使用子类的好教程吗?我可以将此方法与界面生成器一起使用还是应该在代码中重写我的界面? 实际上,Martinj 上面的答案可能更简单,让您不必在任何地方使用自定义子类,在 Interface Builder 等中。【参考方案5】:

您可以将 UIImageView 子类化,然后如果您实现它的 setNeedsDisplay 方法,圆角将适用于子类。 (别忘了导入 QuartzCore)

-(void)setNeedsDisplay 
    self.layer.cornerRadius = 5;
    self.layer.masksToBounds = YES;
    [self.layer setBorderColor:[[UIColor whiteColor] CGColor]];
    [self.layer setBorderWidth: 2.0];

【讨论】:

你不能这样做,setNeedsDisplay 本质上是安排重绘,这就是它的目的。您必须在 init 方法中设置图层。【参考方案6】:

试试这个,

coverImage.image = [UIImage imageWithContentsOfFile:@"coverImage.png"]; 
coverImage.layer.masksToBounds = YES;
coverImage.layer.cornerRadius = 10.0;
coverImage.layer.borderWidth = 1.0;
coverImage.layer.borderColor = [[UIColor brown] CGColor];

这可能会对你有所帮助。

【讨论】:

-1 这并不试图回答这个问题。问题不在于如何生成一个四舍五入的UIImageView(这在问题的代码 sn-p 中成功完成),而是关于如何有效地重用该代码。

以上是关于为所有 UIImageViews 添加圆角的主要内容,如果未能解决你的问题,请参考以下文章

iOS图片设置圆角

使 UIImagePickerController 将所选图像设置为多个 UIImageViews

具有相同图像的多个 UIImageViews 给出不一致错误

以编程方式将 UIImageViews 添加到 UITableViewCell

子类 UIView 不显示添加到它的 UIImageViews

从 GameViewController 访问按钮、标签和 uiimageviews 到 GameScene