I create my views programmatically without using storyboard. And I get this issue "runtime: Layout Issues: Scrollable content size is ambiguous for UIScrollView" from Xcode when debug view hierarchy is opened. I think it is mean that the constraints on scollView is unclear.
I could see the scrollView is showed (yellow color one) in view hierarchy, but its subview UIView is not. Find some solution with storyboard/IB, though I couldn't connect that with my code. Any hint and advice is appreciated.
Below is the scrollView's structure.
ScrollView
->UIView as contentView(coverImageContainer)
-> UIImageView(coverArtImageView)
-> UIButton
// scroller
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
// scrollView.contentMode = .scaleToFill
scrollView.contentInsetAdjustmentBehavior = .never
scrollView.alwaysBounceVertical = true
scrollView.backgroundColor = .yellow
return scrollView
}()
// cover image
lazy var coverImageContainer: UIView = {
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
return containerView
}()
lazy var coverArtImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.layer.cornerRadius = 5
return imageView
}()
lazy var dismissChevron: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.addTarget(self, action: #selector(disimissAction), for: .touchUpInside)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
backingImageView.image = backingImage
view.addSubview(backingImageView)
view.addSubview(dimmerLayer)
view.addSubview(scrollView)
scrollView.addSubview(coverImageContainer)
scrollView.addSubview(stretchySkirt)
coverImageContainer.addSubview(coverArtImageView)
coverImageContainer.addSubview(dismissChevron)
// set layout constraint
configureLayout()
...
}
func configureLayout() {
let g = view.safeAreaLayoutGuide
backingImageleadInset = backingImageView.leadingAnchor.constraint(equalTo: g.leadingAnchor)
backingImageTrailingInset = backingImageView.trailingAnchor.constraint(equalTo: g.trailingAnchor)
backingImageTopInset = backingImageView.topAnchor.constraint(equalTo: view.topAnchor)
backingImageBottomInset = backingImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
NSLayoutConstraint.activate([
backingImageleadInset,
backingImageTrailingInset,
backingImageTopInset,
backingImageBottomInset,
dimmerLayer.leadingAnchor.constraint(equalTo: g.leadingAnchor),
dimmerLayer.trailingAnchor.constraint(equalTo: g.trailingAnchor),
dimmerLayer.topAnchor.constraint(equalTo: view.topAnchor),
dimmerLayer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: backingImageView.topAnchor, constant: 15),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
coverImageContainer.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
coverImageContainer.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 57),
coverImageContainer.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
coverImageContainer.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
coverImageContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -237),
stretchySkirt.topAnchor.constraint(equalTo: coverImageContainer.bottomAnchor),
stretchySkirt.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
stretchySkirt.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
stretchySkirt.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
coverArtImageView.centerXAnchor.constraint(equalTo: coverImageContainer.centerXAnchor),
coverArtImageView.topAnchor.constraint(equalTo: coverImageContainer.topAnchor, constant: 38),
coverArtImageView.leadingAnchor.constraint(equalTo: coverImageContainer.leadingAnchor, constant: 20),
coverArtImageView.trailingAnchor.constraint(equalTo: coverImageContainer.trailingAnchor, constant: -20),
// coverArtImageView.widthAnchor.constraint(equalToConstant: 354),
coverArtImageView.heightAnchor.constraint(equalTo: coverArtImageView.widthAnchor),
dismissChevron.centerXAnchor.constraint(equalTo: coverImageContainer.centerXAnchor),
dismissChevron.topAnchor.constraint(equalTo: coverImageContainer.topAnchor, constant: 4),
])
}
coverImageContainer
that should be the full width of the scroll view - what should its Height be? You indicate you want its Bottom to be-237
, but relative to what? Is that to allow it to scroll up? – DonMagcoverImageContainer
's bottom is related to its superView(scrollView)'s bottom and with an offset-237
. I think that would be ok. – ChuckZHB