0

I want to create a Circle image view for my profile avatar. I have tried this:-

   class CircleImageView: UIImageView {

    override func draw(_ rect: CGRect) {
        // Drawing code

        layer.masksToBounds = true
        layer.cornerRadius = min(rect.width/2 , rect.height/2)
        clipsToBounds = true


    }
}

But its not working.

Avinash kumawat
  • 475
  • 6
  • 18

3 Answers3

1

An extension will be great to set corner or do round image:

extension UIImageView {
    func setRadius(radius: CGFloat? = nil) {
        self.layer.cornerRadius = radius ?? self.frame.width / 2;
        self.layer.masksToBounds = true;
    }
}

Use:

imgview.setRadius(radius: 10)
imgview.setRadius() //default frame.width/2
Bhavin Ramani
  • 3,221
  • 5
  • 30
  • 41
  • It is not wrong at all to extend the UIImageView, but the main purpose of subclassing UIImageView is to let setRadius() works automatically when creating a new instance with any extra method calling – Ahmad F Dec 13 '16 at 08:18
1

Draw function is for drawing not changing layer.

Use layoutSubviews

override func layoutSubviews() {
    super.layoutSubviews()

        layer.masksToBounds = true
        layer.cornerRadius = min(self.frame.width/2 , self.frame.height/2)
        clipsToBounds = true

}
Avinash kumawat
  • 475
  • 6
  • 18
Mohammadalijf
  • 1,387
  • 9
  • 19
1

You are adding the code in the wrong place, drawRect: is not really the right method to do such a functionality for editing the layer, you can achive this by:

Editing the layer when init(frame:) the imageView (also, adding the same functionality in init(coder:) because it should work for both approaches: programmatically and via storyboard):

class CircleImageView: UIImageView {
    override init(frame: CGRect) {
        super.init(frame: frame)

        setupCircleLayer()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setupCircleLayer()
    }

    private func setupCircleLayer() {
        layer.masksToBounds = true
        layer.cornerRadius = min(frame.width/2 , frame.height/2)
        clipsToBounds = true
    }
}

Or as @Mohammadalijf suggested in his answer by overriding layoutSubviews() method:

class CircleImageView: UIImageView {
    override func layoutSubviews() {
        super.layoutSubviews()

        layer.masksToBounds = true
        layer.cornerRadius = min(frame.width/2 , frame.height/2)
        clipsToBounds = true
        backgroundColor = UIColor.black
    }
}

It does the desired fucntionality that you are asking for, but note that:

Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.

i.e, it is related to updating the layout of the view, check the documentation for more information; That's why I prefer to do it in the init methods.

Community
  • 1
  • 1
Ahmad F
  • 30,560
  • 17
  • 97
  • 143
  • In init function autolayout didnt layout the view so the width of the frame will be 0 if created in storyboard. But works fine if you init the view programmatically with frame – Mohammadalijf Dec 13 '16 at 08:19
  • @Mohammadalijf my bad :) I forgot about this point, now it should work fine, thanks for the comment – Ahmad F Dec 13 '16 at 08:32