Denys  Triasunov
Denys Triasunov

Reputation: 569

Using proportional constraints results in glitches on different screen sizes

I've come across this issue while working on a bigger project, but I've simplified it to demonstrate the problem.

I have a UIView in my View Controller that is square and centered:

enter image description here enter image description here

Now, 'Proportional Height' is important here, because the problem does not occur if height or width are set to constant:

enter image description here

I want this view to appear as a nice circle on the phone, so I add an outlet from it to ViewController.swift and provide cornerRadius to view's layer:

class ViewController: UIViewController {

    @IBOutlet weak var centerView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        centerView.layer.cornerRadius = centerView.frame.width / 2
    }

}

When in my Storyboard I set 'View as' to iPhone SE and launch the app on iPhone SE simulator, I get the expected result:

enter image description here enter image description here

But if I do not change 'View as' in Storyboard and launch on iPhone 6 Plus simulator, this is what I get:

enter image description here enter image description here

When I change Storyboard to corresponding screen, it's back to normal:

enter image description here enter image description here

I was hoping it's just a Simulator bug, but same problem occurs when launching on physical devices. So potentially when the app is deployed, users may get messed up UI depending on which screen I chose for my Storyboard while developing?

UPDATE. I should note that adding layoutIfNeeded() to ViewController file resolves the issue:

override func viewDidLoad() {
    super.viewDidLoad()
    view.layoutIfNeeded()
    centerView.layer.cornerRadius = centerView.frame.width / 2
}

But shouldn't layout happen without forcing when app launches no matter on which screen size?

Upvotes: 0

Views: 77

Answers (1)

DonMag
DonMag

Reputation: 77546

Views can change size frequently. If you set the .cornerRadius in viewDidLoad() it won't be reflected if the view changes.

You will be much better off subclassing your UIView:

class RoundedView: UIView {
    override func layoutSubviews() {
        self.layer.cornerRadius = self.bounds.size.height / 2.0
    }
}

and, you can easily make it "designable" so you see the "round view" when laying it out in your storyboard:

@IBDesignable
class RoundedView: UIView {
    override func layoutSubviews() {
        self.layer.cornerRadius = self.bounds.size.height / 2.0
    }
}

Upvotes: 1

Related Questions