Круговий UIImageView в UITableView без хіту продуктивності?


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;

Отже, зараз у мене є квадрат 50х50 зі слабкою сірою рамкою, але я хотів би зробити його круглим, а не в квадраті. Додаток Hemoglobeвикористовує кругові зображення у поданнях таблиці, і саме цього ефекту я хотів би досягти. Однак я не хочу використовувати cornerRadius, оскільки це погіршує мій прокручуваний FPS.

Ось Hemoglobeкруговий показ UIImageViews:

введіть тут опис зображення

Чи є спосіб отримати такий ефект? Дякую.


1
not cornerRadius впливає на продуктивність, masksToBounds / clipsToBounds - проблема
Calin Chitu

Відповіді:


141

Просто встановіть cornerRadiusполовину ширини або висоти (припускаючи, що вигляд вашого об'єкта квадратний).

Наприклад, якщо ширина та висота вигляду об’єкта становлять 50:

itemImageView.layer.cornerRadius = 25;

Оновлення - як зазначає користувач atulkhatri, воно не буде працювати, якщо ви не додасте:

itemImageView.layer.masksToBounds = YES;

30
Чому це може бути найкращою відповіддю? Ну, я не думаю. Використання cornerRadius спричиняє погану продуктивність у режимі прокрутки, особливо на пристроях iPhone4.
Danny Xu

11
Мені сподобалася точка 'встановити cornerRadius на половину ширини або висоти', але просто не забудьте додати 'itemImageView.layer.masksToBounds = ТАК;' а то не спрацює.
атулхатрі

До речі, як прокоментував Денні Сю, це призведе до зниження продуктивності прокрутки таблиці, тому слід уникати в клітинках таблиці.
atulkhatri

4
це має вирішити проблему продуктивності прокрутки табличного перегляду. self.imageView.layer.shouldRasterize = ТАК; self.imageView.layer.rasterizationScale = [UIScreen mainScreen] .scale;
hishboy

Для Swift3: itemImageView.layer.masksToBounds = true;
Лоїс Талагранд,

38

Додати кордон

self.ImageView.layer.borderWidth = 3.0f;

self.ImageView.layer.borderColor = [UIColor whiteColor].CGColor;

Для круглої форми

self.ImageView.layer.cornerRadius = self.ImageView.frame.size.width / 2;
self.ImageView.clipsToBounds = YES;

Перейдіть за цим посиланням

http://www.appcoda.com/ios-programming-circular-image-calayer/


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
iOS - ReactNative

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 ()}
herbert

1
+1 для @herbert. Це повністю спрацювало для мене, коли я замінив layoutSubviews всередині класу, вам слід оновити код
Abdoelrhman

Дякую!! Нарешті я зробив це (підклас, але в Objective-C), щоб обробити деякі кругові UIImageViews, які просто не залишалися б круглими.
Джон Стюарт,

7

Так, можна дати layer.cornerRadius (потрібно додати #import <QuartzCore/QuartzCore.h>)
для створення кругового будь-якого контролю , але в замість вашого випадку набору layerз UIImageViewце найкращий спосіб створити свій імідж кругових і додати його на UIImageViewякому є backGroundColorце ClearColor.

Також зверніться до цього двох джерел коду.

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

і

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

Це може бути корисним у вашому випадку:


4
Нарешті, я думаю, що @iPatel - єдиний, хто дбає про виступ тут. Будьте обережні з cornerRadius, якщо ви хочете отримати високу продуктивність під час прокрутки.
Danny Xu

Я трохи розгублений ... чому ви опублікували посилання на проект перегляду кола? Це не має нічого спільного ні з запитанням, ні з відповіддю, яку ви дали.
user717452

@iPatel - оновлення: друге посилання застаріло автором і більше не може завантажуватися.
trdavidson

3

Встановіть висоту та ширину UIImageView однаковими, наприклад: Height=60& Width = 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

UIImageViewвже поширюється з UIView. У деяких випадках вам може знадобитися обвести деякі UIViews, тому цей метод буде працювати для всіх.
Хоссам Гаріб,

0

Створення кругового перегляду зображення, і це досить просто за допомогою посилання SO нижче, просто створіть власні клітинки для подання таблиці, замість того, щоб розподіляти кожну річ у методі cellForRowAtIndexPath.

як зробити кнопку круглою з фоном зображення в IPhone?

Наведене вище посилання дає вам приклад для кнопок, просто використовуйте їх для перегляду зображень.


0

Якщо ви показуєте зображення на суцільному кольорі фону, простим рішенням може бути використання накладеного зображення з прозорим колом посередині.

Таким чином, ви все ще можете використовувати квадратні зображення та додавати кругові зображення над ними, щоб отримати круговий ефект.

Якщо вам не потрібно маніпулювати своїми зображеннями або показувати їх на складному кольорі фону, це може бути простим рішенням без жодних результатів.


Ні, я не маю. Це просто завантаження, кешування автоматично (ескіз у квадраті) і показ.
swiftcode

Це справді розроблено. Я раніше використовував цей хитрий спосіб. Але це зараз не підходить для моєї нової версії додатка.
Danny Xu

0

Швидко , всередині вашого viewDidLoadметоду, з 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

Не забудьте змінити метод cornerRadius у viewDidLayoutSubviews вашого UIView.

Приклад:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.imageView.layer.cornerRadius = self.imageView.frame.size.width / 2;
    self.imageView.clipsToBounds = true
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.