David Seek
David Seek

Reputation: 17132

Swift / cornerRadius and masksToBounds lets UIImageView disappear

I have a UITableViewController with a UIImageView. The content is loaded with the following simple code.

@IBOutlet weak var avatarImageView: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    updateUI()
}

func updateUI() {

    backendless.userService.currentUser.retrieveProperties()

    avatarImageView.layer.cornerRadius = avatarImageView.frame.size.width/2
    avatarImageView.layer.masksToBounds = true

    let imgURL = NSURL(string: (backendless.userService.currentUser.getProperty("Avatar") as? String)!)
    avatarImageView.sd_setImageWithURL(imgURL)

    tableView.reloadData()

}

The ImageView does not appear.

But if I delete the following code, the UIImageView will be set and displayed correctly.

avatarImageView.layer.cornerRadius = avatarImageView.frame.size.width/2
avatarImageView.layer.masksToBounds = true

What am I missing? Help is very appreciated.:

PS:

Xcode 8.0

Swift 2.3

Contrains for ImageView are set to 120*120

sd_setImageWithURL = pod 'SDWebImage'

enter image description here

Upvotes: 4

Views: 1395

Answers (4)

user5899631
user5899631

Reputation:

“xy.view.layoutIfNeeded()” 

needs to be called everytime i’m calling a property before the view has finished loading for example imageView.view.layoutIfNeeded() to call for the height and widths values

Upvotes: 0

Alex L
Alex L

Reputation: 111

Try this:

override func viewDidLoad() {
    super.viewDidLoad()

    self.view.layoutIfNeeded() // <- This will update your initial view frames
    updateUI()
}

What is happening is that in Xcode 8.0, by the time you hit viewDidLoad, the frame of all subviews of a controller is still x: 0.0, y: 0.0, w: 1000.0, h: 1000.0, so in effect you're making the corner radius of your avatar image view 500.0pt. When you call layout if needed, the correct frames will be calculated, and give you the value you're expecting.

Upvotes: 5

matt
matt

Reputation: 535192

One obvious problem is that you are calling updateUI too soon. In viewDidLoad, there is no UI. The view has loaded but that is all; it is not in the interface and no layout has yet taken place. Your code depends upon avatarImageView.frame, but we do not yet know what that is. You have constraints on the image view, but they have not yet taken effect! Thus you should postpone this call until after the interface is present, e.g. viewDidAppear or at least viewDidLayoutSubviews. But of course then you probably only want to call it once (typed in browser, not tested, but it will be something like this):

var didConfigureUI = false
func viewDidLayoutSubviews() {
    if !didConfigureUI {
        didConfigureUI = true
        updateUI()
    }
}

Upvotes: 4

Mahesh Agrawal
Mahesh Agrawal

Reputation: 3358

I think your problem with your controller. You have added the image view to a UITableViewController. That means constraint set to image view will not work if you use the frame in view did load. You need to change frame of the UIIMageView before use it or you need to use UIViewController. use the below code before using the frame of image view.

avatarImageView.frame.size.width = 120.0
avatarImageView.frame.size.height = 120.0

I think this will solve the problem. But you should use UIViewController if there is no special purpose of UITableViewController.

Upvotes: 1

Related Questions