John Doah
John Doah

Reputation: 1999

Trying to create a circle UIImageView causing it to disappear

I have a simple UIImageView, trying to set it's cornerRadius to be half of it's width, causing the Image to disappear. This is what I have:

    private let profileImg: UIImageView = {
    let img = UIImageView(image: UIImage(named: "profileplaceholder"))
    img.translatesAutoresizingMaskIntoConstraints = false
    img.heightAnchor.constraint(equalToConstant: 100).isActive = true
    img.widthAnchor.constraint(equalToConstant: 100).isActive = true

    img.layer.borderWidth = 1.0
    img.layer.borderColor = UIColor.appPurple.cgColor
    img.layer.cornerRadius = (img.frame.width / 2)
    img.clipsToBounds = true
    img.layer.masksToBounds = true
    img.contentMode = .scaleAspectFill

    return img
}()

I just don't get what's wrong here, and why the image won't show at all.

Upvotes: 0

Views: 79

Answers (2)

Saifan Nadaf
Saifan Nadaf

Reputation: 1775

The issue is it has not getting proper frame of your imageview while setting the cornerRadius.

After adding/changing constraints you can use layoutIfNeeded() it will force the layout of your view.

This code worked for me

class ViewController: UIViewController {

    var profileImageView : UIImageView = {
        let img = UIImageView(image: UIImage(named: "0266554465"))

        img.translatesAutoresizingMaskIntoConstraints = false

        img.heightAnchor.constraint(equalToConstant: 300).isActive = true
        img.widthAnchor.constraint(equalToConstant: 300).isActive = true

        img.layoutIfNeeded()
        img.layer.borderWidth = 1.0
        img.layer.cornerRadius = (img.frame.width / 2)
        img.clipsToBounds = true
        return img
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

         self.view.addSubview(self.profileImageView)

        let centerXConstraint = NSLayoutConstraint(item: profileImageView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)

        let centerYConstraint = NSLayoutConstraint(item: profileImageView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)

        view.addConstraints([centerXConstraint, centerYConstraint])
    }

}

Upvotes: 2

BevTheDev
BevTheDev

Reputation: 583

This is happening because you're setting the image view's size with constraints, but then using the frame to calculate the corner radius before the constraints have been applied. If you try printing out what img.frame.width returns, you should see that it's not "50" as you might expect.

A quick fix is to hardcode the corner radius to the size you want, but I would recommend you instead separate the image view creation from the rest of the logic. Ideally put the imageView/stackView in a xib and set the corner radius in viewDidLoad(). That would ensure the constraints are in effect before you need to retrieve the view's frame.

Another recommendation - your code as-is will recreate the image view every time you use profileImg, which is inefficient and may result in unexpected behavior (i.e. editing the profile image may not work.) Changing profileImg to an IBOutlet will solve this for you, or you can set its value in your init() to ensure it is only initialized once.

Upvotes: 0

Related Questions