web-dev-qa-db-fra.com

UIImageView circulaire dans UITableView sans performance?

J'ai un UIImageView sur chacune de mes cellules UITableView, qui affichent une image distante (avec SDWebImage). J'ai créé un style de calque QuartzCore dans la vue image, en tant que tel:

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

Alors maintenant, j'ai un carré 50x50 avec une bordure gris pâle, mais j'aimerais le rendre circulaire au lieu de carré. L'application Hemoglobe utilise des images circulaires dans les vues de tableau, et c'est l'effet que je souhaite obtenir. Cependant, je ne veux pas utiliser cornerRadius, cela dégrade mon FPS en défilement.

Voici Hemoglobe montrant une circulaire UIImageViews:

enter image description here

Y a-t-il un moyen d'obtenir cet effet? Merci.

79
swiftcode

Réglez simplement le cornerRadius sur la moitié de la largeur ou de la hauteur (en supposant que la vue de votre objet soit carrée).

Par exemple, si la largeur et la hauteur de la vue de votre objet sont égales à 50:

itemImageView.layer.cornerRadius = 25;

Mise à jour - Comme le fait remarquer l'utilisateur atulkhatri, cela ne fonctionnera pas si vous n'ajoutez pas:

itemImageView.layer.masksToBounds = YES;
137
tagabek

Ajouter une bordure

self.ImageView.layer.borderWidth = 3.0f;

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

Pour forme circulaire

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

Référer ce lien

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

38
yazh

Utilisez ce code .. Cela vous sera utile ..

    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();

Ça fonctionne bien pour moi. :)

14
shivam

Voici une méthode plus à jour dans Swift utilisant IBDesignable et IBInspectable pour la sous-classe 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()
    }
}
10
Antzi

Oui, il est possible de donner layer.cornerRadius (besoin d'ajouter #import <QuartzCore/QuartzCore.h>)
pour créer un contrôle circulaire, mais dans votre cas, au lieu de définir layer sur UIImageView, il s'agit du meilleur moyen de créer votre image de manière circulaire et de l'ajouter à UIImageView Qui ont backGroundColor est ClearColor.

Reportez-vous également à cette source de code Two.

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

et

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

Cela pourrait être utile dans votre cas:

7
iPatel

Définissez la hauteur et la largeur de UIImageView pour qu'elles soient identiques, par exemple: Height=60 & Width = 60, alors le cornerRadius devrait être exactement le demi. Je l'ai gardé 30 dans mon cas. Cela a fonctionné pour moi.

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

Si vous utilisez des autolayout et des hauteurs de cellules différentes, vous feriez mieux de le faire de cette façon:

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

J'utilise une classe Round Image View… Je ne l'utilise donc qu'à la place de UIImageView et je n'ai rien à modifier…

Cette classe trace également une bordure facultative autour du cercle. Il y a souvent une bordure autour des images arrondies.

Ce n'est pas une sous-classe UIImageView, car UIImageView possède son propre mécanisme de rendu et n'appelle pas la méthode drawRect.

Interface:

#import <UIKit/UIKit.h>

@interface MFRoundImageView : UIView

@property(nonatomic,strong) UIImage* image;

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

@end

mise en œuvre:

#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
Moose

Solution utilisable dans Swift en utilisant extension:

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

Usage:

self.venueImageView.circleMe()
1
Hossam Ghareeb

Si vous affichez les images sur une couleur d'arrière-plan unie, une solution simple consiste peut-être à utiliser une image superposée avec un cercle transparent au milieu.

De cette façon, vous pouvez toujours utiliser des images carrées et ajouter l'image circulaire au-dessus d'elles pour obtenir l'effet circulaire.

Si vous n'avez pas besoin de manipuler vos images ou de les afficher sur une couleur d'arrière-plan complexe, il peut s'agir d'une solution simple, sans impact négatif sur les performances.

0
Eyal

Créer une vue d’image circulaire est très facile avec le lien ci-dessous SO, vous n'avez que des cellules personnalisées pour votre vue tableau au lieu d’allouer tout dans votre méthode cellForRowAtIndexPath.

comment faire un bouton rond avec un fond d'image dans IPhone?

Le lien ci-dessus vous donne un exemple de boutons, utilisez-le simplement pour vos vues d'image.

0
Saify

En Swift, dans votre méthode viewDidLoad, avec la sortie 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
lifeisfoo

In Swift utilisez cette extension pour CircularImageView ou 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
    }

}

tilisation:

self.ImageView.circular()
self.ImageView.roundedCorner()
0
Aqib Mumtaz