Search code examples
swiftuiscrollviewuiimageviewautolayoutsnapkit

Making UIScrollView with an UIImageView scale content automatically using Swift, autolayout and SnapKit


I have a view controller set up in Interface Builder with the following view structure:

- UIView
   * UIScrollView
      * UIImageView

I want to assign an image to UIImageView so, that the scroll view (and it's content size) will adopt the same width than in the image and automatically calculate the height of the content size according to the image aspect ratio. (This makes the image vertically scrollable inside the UIScrollView.)

I'm using Swift and Interface Builder + SnapKit for managing autolayout constraints.


Solution

  • I managed to make the constraints using SnapKit in the following way:

    • In Interface Builder, select the view controller and create all missing constraints by selecting Editor / Resolve Auto Layout Issues / Add Missing Constraints
    • Manually select all generated constraints and select Placeholder / Remove at build time from Attributes Inspector
    • Assign UIScrollView and UIImageView outlets to the view controller
    • Assign an image to the UIImageView

    Then implement the view controller as follows:

    import UIKit
    import SnapKit
    
    class ViewController: UIViewController {
        @IBOutlet weak var scrollView: UIScrollView!
        @IBOutlet weak var imageView: UIImageView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            scrollView.snp.makeConstraints { (make) in
                make.edges.equalTo(view)
            }
    
            let ratio = imageView.image!.size.height / imageView.image!.size.width
            imageView.snp.makeConstraints { (make) in
                make.top.equalTo(0.0)
                make.bottom.equalTo(scrollView.snp.bottom)
                make.width.equalTo(view.snp.width)
                make.height.equalTo(scrollView.snp.width).multipliedBy(ratio)
            }
        }
    }