In this view controller, I initialize a UIScrollView
, add it to the hierarchy and add autolayout constraints in viewDidLoad
, and add an image subview in viewDidLayoutSubviews
. If I assign this to a free-standing view in Storyboard, it behaves as expected (square scroll view with an image, I can scroll around). However, if I embed this view in a navigation controller, making no other changes, I instead get a black screen that fills the window, sans image.
Why is this happening, and how can I fix it? I've seen other questions [1] [2] that suggest setting the content size. However, I'm trying to use autolayout rather than setting the content size directly.
Here is a minimal but complete example. Again: works with freestanding view, not when embedded:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
var scrollView: UIScrollView = UIScrollView(frame: CGRectZero)
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.delegate = self
self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(self.scrollView)
self.scrollView.maximumZoomScale = 2
self.scrollView.minimumZoomScale = 1
self.view.setTranslatesAutoresizingMaskIntoConstraints(false)
self.configureAutolayout()
}
override func viewDidLayoutSubviews() {
if let x = UIImage(named: "photo.jpg") {
let y = UIImageView(image: x)
self.scrollView.addSubview(y)
}
}
func configureAutolayout() {
var constraint = NSLayoutConstraint(item: self.scrollView,
attribute: .Leading,
relatedBy: .Equal,
toItem: self.view,
attribute: .Leading,
multiplier: 1,
constant: 0)
self.view.addConstraint(constraint)
constraint = NSLayoutConstraint(item: self.scrollView,
attribute: .Trailing,
relatedBy: .Equal,
toItem: self.view,
attribute: .Trailing,
multiplier: 1,
constant: 0)
self.view.addConstraint(constraint)
constraint = NSLayoutConstraint(item: self.scrollView,
attribute: .Top,
relatedBy: .Equal,
toItem: self.topLayoutGuide,
attribute: .Bottom,
multiplier: 1,
constant: 0)
self.view.addConstraint(constraint)
constraint = NSLayoutConstraint(item: self.scrollView,
attribute: .Height,
relatedBy: .Equal,
toItem: self.scrollView,
attribute: .Width,
multiplier: 1,
constant: 0)
self.view.addConstraint(constraint)
}
func viewForZoomingInScrollView(scrollView: UIScrollView!) -> UIView! {
return self.scrollView.subviews.first as UIView
}
}
EDIT:
Removing the following line fixes one problem and introduces another:
self.view.setTranslatesAutoresizingMaskIntoConstraints(false)
The UIScrollView
, with the image subview, now appear both in the independent view and when embedded in the navigation controller. However, there is now an extra, unwanted space at the top of the scrollview of the embedded controller. I thought that TopLayoutGuide
was the appropriate view for alignment--is this not the case?
EDIT 2:
The inset problem was fixed by setting self.automaticallyAdjustsScrollViewInsets
to false
, as per this question [3]. It is not behaving as intended.
References:
[1] UIScrollView not scrolling when included into viewcontroller embedded into a navigation controller
[2] UIScrollView scroll not working after pushed with a navigation controller