UITableView中的圆形UIImageView是否对性能没有影响?


82

我的UIImageView每个UITableView单元格上都有一个,用于显示远程图像(使用SDWebImage)。我已经QuartzCore对图像视图进行了一些图层样式设置,如下所示:

UIImageView *itemImageView = (UIImageView *)[cell viewWithTag:100];
    itemImageView.layer.borderWidth = 1.0f;
    itemImageView.layer.borderColor = [UIColor concreteColor].CGColor;
    itemImageView.layer.masksToBounds = NO;
    itemImageView.clipsToBounds = YES;

所以现在我有一个50x50的正方形,带有淡淡的灰色边框,但是我想使其变为圆形而不是正方形。该应用程序Hemoglobe在表格视图中使用圆形图像,这就是我想要实现的效果。但是,我不想使用cornerRadius,因为那样会使滚动FPS降低。

这是Hemoglobe圆形的UIImageViews

在此处输入图片说明

有什么办法可以达到这种效果?谢谢。


1
不是cornerRadius会影响性能,masksToBounds / clipsToBounds是问题
Calin Chitu

Answers:


141

只需将cornerRadius宽度或高度的一半设置为(假设对象的视图为正方形)。

例如,如果对象的视图的宽度和高度均为50:

itemImageView.layer.cornerRadius = 25;

更新-正如atulkhatri用户指出的那样,如果您不添加,它将不起作用:

itemImageView.layer.masksToBounds = YES;

30
为什么这是最好的答案?好吧,我不这么认为。使用cornerRadius会导致滚动视图中的性能下降,尤其是在iPhone4设备中。
Danny Xu

11
我喜欢点“将cornerRadius设置为宽度或高度的一半”,但不要忘了添加“ itemImageView.layer.masksToBounds = YES;”。否则它将无法正常工作。
atulkhatri 2014年

顺便说一句,正如Danny Xu所说,它将降低表视图的滚动性能,因此应避免在表视图单元格中使用。
atulkhatri 2014年

4
这应该可以解决您的tableview滚动性能问题。self.imageView.layer.shouldRasterize = YES; self.imageView.layer.rasterizationScale = [UIScreen mainScreen] .scale;
hishboy 2014年

对于Swift3:itemImageView.layer.masksToBounds = true;
罗伊斯·塔拉格朗德


14

使用此代码。将对您有所帮助。

    UIImage* image = ...;
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
    // Add a clip before drawing anything, in the shape of an rounded rect
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                cornerRadius:50.0] addClip];
    // Draw your image
    [image drawInRect:imageView.bounds];

    // Get the image, here setting the UIImageView image
    imageView.image = UIGraphicsGetImageFromCurrentImageContext();

    // Lets forget about that we were drawing
    UIGraphicsEndImageContext();

这对我来说可以。:)


使用此代码真的非常简单!!感谢@Shivam
Anilkumar iOS-ReactNative 2014年

10

这是使用IBDesignable和IBInspectable继承UIImageView的快速更新方法

@IBDesignable class RoundableUIImageView: UIImageView {
    private var _round = false
    @IBInspectable var round: Bool {
        set {
            _round = newValue
            makeRound()
        }
        get {
            return self._round
        }
    }
    override internal var frame: CGRect {
        set {
            super.frame = newValue
            makeRound()
        }
        get {
            return super.frame
        }

    }

    private func makeRound() {
        if self.round == true {
            self.clipsToBounds = true
            self.layer.cornerRadius = (self.frame.width + self.frame.height) / 4
        } else {
            self.layer.cornerRadius = 0
        }
    }

    override func layoutSubviews() {
            makeRound()
    }
}

我不得不添加以下代码,使之为我工作(表视图细胞内):覆盖FUNC layoutSubviews(){makeRound()}
赫伯特

1
@herbert +1。当我在类中重写layoutSubviews时,这对我完全
有用

谢谢!!我终于做到了这一点(子类,但是在Objective-C中)来处理一些圆形的UIImageViews,这些UIImageViews不会一直停留。
约翰·斯图尔特

7

是的,这可能给layer.cornerRadius (需加 #import <QuartzCore/QuartzCore.h>
为创建循环的任何控制,但在你的情况,而不是一套layerUIImageView它是最好的方法制作图片为圆形,并将其添加在UIImageView其中有backGroundColorClearColor

另请参阅这两个代码源。

https://www.cocoacontrols.com/controls/circleview

https://www.cocoacontrols.com/controls/mhlazytableimages

这可能对您有帮助:


4
最后,我认为@iPatel是唯一关心此处性能的人。如果要在滚动时获得高性能,请注意cornerRadius。
Danny Xu

我有些困惑...为什么要发布圈子视图项目链接?这与问题无关,也与您给出的答案无关。
user717452 2014年

@iPatel-更新:第二个链接已被作者弃用,无法再下载。
trdavidson

3

设置UIImageView的高度和宽度为相同的值,例如:Height=60Width = 60,然后cornerRadius应该恰好是一半。在我的情况下,我将其保留为30。

 self.imageView.layer.cornerRadius = 30;
 self.imageView.layer.borderWidth = 3;
 self.imageView.layer.borderColor = [UIColor whiteColor].CGColor;
 self.imageView.layer.masksToBounds = YES;

2

如果使用一些自动布局和不同的单元格高度,则最好采用以下方式:

   override func layoutSubviews() {
        super.layoutSubviews()
        logo.layer.cornerRadius = logo.frame.size.height / 2;
        logo.clipsToBounds      = true;
    }

1

我使用的是Round Image View类……所以我只用它而不是UIImageView,也没有什么要调整的……

该类还在圆周围绘制可选边框。圆形图片周围经常有边框。

它不是UIImageView子类,因为UIImageView具有其自己的呈现机制,并且不调用drawRect方法。

介面

#import <UIKit/UIKit.h>

@interface MFRoundImageView : UIView

@property(nonatomic,strong) UIImage* image;

@property(nonatomic,strong) UIColor* strokeColor;
@property(nonatomic,assign) CGFloat strokeWidth;

@end

实施方式:

#import "MFRoundImageView.h"


@implementation MFRoundImageView

-(void)setImage:(UIImage *)image
{
    _image = image;
    [self setNeedsDisplay];
}

-(void)setStrokeColor:(UIColor *)strokeColor
{
    _strokeColor = strokeColor;
    [self setNeedsDisplay];
}

-(void)setStrokeWidth:(CGFloat)strokeWidth
{
    _strokeWidth = strokeWidth;
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGPathRef path = CGPathCreateWithEllipseInRect(self.bounds, NULL);
    CGContextAddPath(ctx, path);
    CGContextClip(ctx);
    [self.image drawInRect:rect];

    if ( ( _strokeWidth > 0.0f ) && _strokeColor ) {
        CGContextSetLineWidth(ctx, _strokeWidth*2); // Half border is clipped
        [_strokeColor setStroke];
        CGContextAddPath(ctx, path);
        CGContextStrokePath(ctx);
    }
    CGPathRelease(path);
}

@end

1

在可用的解决方案Swift使用extension

extension UIView{
  func circleMe(){
      let radius = CGRectGetWidth(self.bounds) / 2
      self.layer.cornerRadius = radius
      self.layer.masksToBounds = true
  }
}

用法:

self.venueImageView.circleMe()

将扩展名应用于会更好UIImageView吗?该代码有效,但是使扩展名对任何UIView对象通用。
swiftcode '16

UIImageView已经从扩展UIView。在某些情况下,您可能需要圈一些UIViews,因此此方法将适用于所有人。
Hossam Ghareeb,2013年


0

如果以纯背景色显示图像,则一个简单的解决方案是使用中间带有透明圆圈的覆盖图像。

这样,您仍然可以使用方形图像,并在其上方添加圆形图像以获得圆形效果。

如果您不需要操纵图像或以复杂的背景颜色显示图像,这可以是一种简单的解决方案,而不会影响性能。


不,我没有。只需简单的加载,即可自动缓存(方形缩略图)并显示。
swiftcode

真的很锻炼。我以前用过这种棘手的方法。但这现在不适合我的新版本应用程序。
Danny Xu

0

您的viewDidLoad方法中,通过swift快速地将其userImage输出:

self.userImage.layer.borderWidth = 1;
self.userImage.layer.borderColor = UIColor.whiteColor().CGColor;
self.userImage.layer.cornerRadius = self.userImage.frame.size.width / 2;
self.userImage.clipsToBounds = true;

0

在Swift中,将此扩展用于CircularImageView或RoundedImageView:

extension UIView {

    func circular(borderWidth: CGFloat = 0, borderColor: UIColor = UIColor.whiteColor()) {
        let radius = CGRectGetWidth(self.bounds) / 2
        self.layer.cornerRadius = radius
        self.layer.masksToBounds = true

        self.layer.borderWidth = borderWidth
        self.layer.borderColor = borderColor.CGColor
    }

    func roundedCorner(borderWidth: CGFloat = 0, borderColor: UIColor = UIColor.whiteColor()) {
        let radius = CGRectGetWidth(self.bounds) / 2
        self.layer.cornerRadius = radius / 5
        self.layer.masksToBounds = true

        self.layer.borderWidth = borderWidth
        self.layer.borderColor = borderColor.CGColor
    }

}

用法:

self.ImageView.circular()
self.ImageView.roundedCorner()

0

对于圆形图像视图,请使用以下代码。

self.imageView.layer.cornerRadius = self.imageView.frame.size.width / 2;
self.imageView.clipsToBounds = true

不要忘记在UIView的viewDidLayoutSubviews方法中更改cornerRadius。

例:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.imageView.layer.cornerRadius = self.imageView.frame.size.width / 2;
    self.imageView.clipsToBounds = true
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.