Fixing Rotation Issues – Easily Redrawing Custom Subviews

I’ve been working a lot lately with zero Storyboards and doing everything programmatically. It’s a nice fresh approach for me, and has surprisingly even helped me understand the mechanics of Storyboards better.

But I kept running into a rotation issue.

Here’s a sample Custom View I made called HomeView. It sets up a label and constrains it to the middle of the view.

import UIKit

class HomeView: UIView {
    
    let myLabel: UILabel = {
        let label = UILabel()
        label.text = "Hello!"
        label.translatesAutoresizingMaskIntoConstraints = false
        label.backgroundColor = .red
        label.clipsToBounds = true
        label.layer.cornerRadius = 20
        label.font = label.font.withSize(50)
        label.textAlignment = .center
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(myLabel)
        setupConstraints()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setupConstraints() {
        NSLayoutConstraint.activate([
            myLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
            myLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
            myLabel.widthAnchor.constraint(equalToConstant: 200),
            myLabel.heightAnchor.constraint(equalToConstant: 200)
        ])
    }
}

For the main View Controller, I created an instance of the HomeView. That instance is then added as a subview of the View Controller’s view.

import UIKit

class ViewController: UIViewController {
    
    var homeView = HomeView(frame: UIScreen.main.bounds)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .blue
        view.addSubview(homeView)
    }
}

While everything worked fine in portrait mode – landscape mode decided to hurt my eyes.

What was causing this is that the homeView instance was setting its frame to the UIScreen.main.bounds. Upon rotation, homeView wasn’t being updated to the new screen’s bounds.

I found a super simple solution of two lines that allowed for the redraw of homeView.

self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.contentMode = .redraw

Adding this to the override init in the Custom View made everything work perfectly.

override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(myLabel)
        setupConstraints()
        self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        self.contentMode = .redraw
    }

Leave a Comment

Your email address will not be published. Required fields are marked *