Reputation: 879
I was searching how to update the UIs when the device orientation has changed, but I'm stuck now and need some help.
I made a login screen with Swift and created its UIs programmatically. For the supported orientation in the info.plist, I set
and this is the login screen.
When I build and run with Portrait, it works fine, but when I rotate the device, the UI becomes like this.
it's like the device orientation is changed to landscape, but the UI's remain portrait, so the right side of the screen becomes black.
This is the view file (I didn't put the whole code), and I have a stack view contains other UIs.
class LoginView: UIView {
lazy private var stackView = UIStackView()
override init(frame: CGRect) {
super.init(frame: frame)
setupStackView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupStackView() {
stackView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(stackView)
stackView.axis = .vertical
stackView.alignment = .fill
stackView.spacing = 20
stackView.distribution = .fill
stackView.addArrangedSubview(titleText)
stackView.addArrangedSubview(greenView)
NSLayoutConstraint.activate([
stackView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.9),
stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor)
])
}
and the view controller is like this.
class LoginViewController: UIViewController {
private let loginView = LoginView()
override func viewDidLoad() {
view.addSubview(loginView)
loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
print("the view is rotated")
}
}
I get the message "the view is rotated" printed, and the rotation part seems it does not have a problem, but cannot update the view controller itself to horizontal and update the UIs.
I was wondering why my view controller stays vertical when the device is in landscape mode, and how to update it.
Could anyone please lead me to the right direction, please?
Upvotes: 1
Views: 7350
Reputation: 764
Actually by using
loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
you assign a frame to your login view which will not change on device rotation.
you might wanna use a constraint approach here as well:
// try replacing
// loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
// with
loginView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
loginView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
loginView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
loginView.topAnchor.constraint(equalTo: view.topAnchor),
loginView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
Another approach would be updating the frame of your login view e.g.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
}
Last but not least you can use autoresizingMask in viewDidLoad
loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
loginView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
P.S. My previous comment was misleading since the login frame wasn't set in the setupStackView() function
and my final comment:
// you can replace
loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
// with
loginView.frame = view.bounds
Upvotes: 4