Home > Software design >  Variable-width StackView?
Variable-width StackView?

Time:06-15

This is my code:

import UIKit

class DocumentViewController: UIViewController, UIScrollViewDelegate {
    
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return scrollViewContainer
    }
    
    func scrollViewDidZoom(_ scrollView: UIScrollView) {
        let scrollViewSize = scrollView.bounds.size
        let scrollViewContainerSize = scrollViewContainer.frame.size
        let verticalPadding = scrollViewContainerSize.height < scrollViewSize.height ? (scrollViewSize.height - scrollViewContainerSize.height) / 2 : 0
        let horizontalPadding = scrollViewContainerSize.width < scrollViewSize.width ? (scrollViewSize.width - scrollViewContainerSize.width) / 2 : 0
        scrollView.contentInset = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
    }
  
    let scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.minimumZoomScale = 0.1
        scrollView.maximumZoomScale = 4.0
        scrollView.zoomScale = 1.0
        return scrollView
    }()
  
    let scrollViewContainer: UIStackView = {
        let view = UIStackView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.axis = .vertical
        view.spacing = 15
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self
        view.backgroundColor = .gray
        view.addSubview(scrollView)
        scrollView.addSubview(scrollViewContainer)
        
        let uiview1 = UIView(frame: .zero)
        uiview1.heightAnchor.constraint(equalToConstant: 1000).isActive = true
        uiview1.widthAnchor.constraint(equalToConstant: 1000).isActive = true
        scrollViewContainer.addArrangedSubview(uiview1)
        uiview1.backgroundColor = .white
        
        let uiview2 = UIView(frame: .zero)
        uiview2.heightAnchor.constraint(equalToConstant: 1000).isActive = true
        uiview2.widthAnchor.constraint(equalToConstant: 1000).isActive = true
        scrollViewContainer.addArrangedSubview(uiview2)
        uiview2.backgroundColor = .white
        
        let uiview3 = UIView(frame: .zero)
        uiview3.heightAnchor.constraint(equalToConstant: 1000).isActive = true
        uiview3.widthAnchor.constraint(equalToConstant: 1000).isActive = true
        scrollViewContainer.addArrangedSubview(uiview3)
        uiview3.backgroundColor = .white
        
        let uiview4 = UIView(frame: .zero)
        uiview4.heightAnchor.constraint(equalToConstant: 1000).isActive = true
        uiview4.widthAnchor.constraint(equalToConstant: 1000).isActive = true
        scrollViewContainer.addArrangedSubview(uiview4)
        uiview4.backgroundColor = .white
        
        let uiview5 = UIView(frame: .zero)
        uiview5.heightAnchor.constraint(equalToConstant: 1000).isActive = true
        uiview5.widthAnchor.constraint(equalToConstant: 2000).isActive = true
        scrollViewContainer.addArrangedSubview(uiview5)
        uiview5.backgroundColor = .white
        
        showBounds()
        setConstraints()
    }
    
    func setConstraints() {
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        scrollViewContainer.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        scrollViewContainer.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
        scrollViewContainer.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        scrollViewContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
        
    }
        
    func showBounds() {
        view.layer.borderWidth = 5.0
        view.layer.borderColor = UIColor.blue.cgColor
        scrollViewContainer.layer.borderWidth = 5.0
        scrollViewContainer.layer.borderColor = UIColor.red.cgColor
        scrollView.layer.borderWidth = 3.0
        scrollView.layer.borderColor = UIColor.yellow.cgColor
    }

}

This code gives the following behaviour: https://i.stack.imgur.com/gNxnD.gif

You can see that whereas the last test UIView I made in viewDidLoad has a width of 2000, it ends up being cut off for some reason, as if its width is 1000. Additionally, if I change the width of the last view to 500, I get this behaviour.

So it seems that scrollViewContainer (?) is resizing to the smallest width out of those test UIViews. All I want is for it to allow different sized views, with the default width being the widest child view, as in this mockup.

CodePudding user response:

You need to add 'alignment' to your stack view. Please try this:

let scrollViewContainer: UIStackView = {
    let view = UIStackView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.axis = .vertical
    view.alignment = .center
    view.spacing = 15
    return view
}()
  • Related