rdk
rdk

Reputation: 109

iOS UIKit StackView and handling device rotation properly

I'm working on an app that uses a Scrollview -> StackView -> button, imageview, textview view hierarchy. (I'm building the view programmatically rather than using storyboard. I'm using a scrollview as the top view so it will handle pinch/zoom for me.

If I start the app in portrait mode, things layout like I want. If I then rotate to landscape, the layout does not adjust properly. Same for starting in landscape and then rotating to portrait -- the layout does not adjust correctly.

Here is the layout if I start in portrait. Next image is when I rotate to landscape.

enter image description here

enter image description here

enter image description here

enter image description here

Here is snippets of sample code.

scrollView.frame = view.bounds
scrollView.delegate = self
scrollView.zoomScale = 1.0
scrollView.maximumZoomScale = 5.0
scrollview.minimumZoomScale = 0.5
scrollView.frame = view.bounds

imageView.backgroundColor = .systemGreen
imageView.image = UIImage(systemName: "bell")
imageView.contentMode = .scaleAspectFit

textView.text = "This is a bunch of text blah blah"

stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(label)
stackView.addArrangedSubview(textView)
stackView.axis = .vertical
stackView.distribution = .fillEqually
stackView.spacing = 20

scrollView.addSubview(stackView)
view.addSubview(scrollView)

Any pointers and suggestions would be greatly appreciated.

I'd like to be able to properly handle device rotation. Images show rotation results.

Upvotes: -2

Views: 176

Answers (1)

Fabio
Fabio

Reputation: 5628

Your code and your goal are a little bit confused, if I understand well you can do it with autoLayout, take a look to my example below:

class YourViewController: UIViewController {

// Declare your constant
let scrollView = UIScrollView()
let imageView = UIImageView()
let textView = UITextView()
let label = UILabel()
let myBGView = UIView()
let stackView = UIStackView()

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .red
    setupUI()
    setupConstraints()
}

// Setup UI elements
fileprivate func setupUI() {
    myBGView.backgroundColor = .systemYellow
    label.backgroundColor = .systemBlue
    label.text = "Hello World"
    label.textAlignment = .center
    label.font = .systemFont(ofSize: 16, weight: .bold)
    
    textView.backgroundColor = .white
    textView.isUserInteractionEnabled = false
    textView.text = "This is a bunch of text\nMore text on this line\nEven more text"
    
    scrollView.backgroundColor = .red
    scrollView.zoomScale = 1.0
    scrollView.maximumZoomScale = 5.0
    scrollView.minimumZoomScale = 0.5
    
    imageView.backgroundColor = .systemGreen
    imageView.image = UIImage(systemName: "bell")
    imageView.contentMode = .scaleAspectFit
    
    stackView.axis = .vertical
    stackView.distribution = .fillEqually
    stackView.spacing = 20
    stackView.addArrangedSubview(imageView)
    stackView.addArrangedSubview(label)
    stackView.addArrangedSubview(textView)
    
    view.addSubview(scrollView)
    scrollView.addSubview(myBGView)
    myBGView.addSubview(stackView)
}

//setup constraints

fileprivate func setupConstraints() {
    
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    myBGView.translatesAutoresizingMaskIntoConstraints = false
    stackView.translatesAutoresizingMaskIntoConstraints = false
    
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    
    myBGView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
    myBGView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    myBGView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    myBGView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
    myBGView.heightAnchor.constraint(equalToConstant: 299).isActive = true
    
    stackView.topAnchor.constraint(equalTo: myBGView.topAnchor, constant: -1).isActive = true
    stackView.leadingAnchor.constraint(equalTo: myBGView.leadingAnchor).isActive = true
    stackView.trailingAnchor.constraint(equalTo: myBGView.trailingAnchor).isActive = true
    stackView.bottomAnchor.constraint(equalTo: myBGView.bottomAnchor).isActive = true
  }
}

This is the result:

enter image description here

Landscape rotation

enter image description here

Simply open a new project and paste the code, if I correctly understand your question this is a good start point for you.

Upvotes: 2

Related Questions