I have an iOS view consisting of a collectionView with a headerView. The view displays fine, but when I rotate the device (iPad), the header elements get duplicated and don't fit correctly. The output window shows the following
(
"<NSLayoutConstraint:0x600000051860 H:|-(0)-[UIImageView:0x7fe602031e40] (active, names: '|':MYAPP.HeaderCollectionReusableView:0x7fe602031c40 )>",
"<NSLayoutConstraint:0x600000053a20 UIImageView:0x7fe602031e40.trailing == MYAPP.HeaderCollectionReusableView:0x7fe602031c40.trailing (active)>",
"<NSLayoutConstraint:0x600000050be0 UIImageView:0x7fe602031e40.width == 1024 (active)>",
"<NSLayoutConstraint:0x6000000218b0 'UIView-Encapsulated-Layout-Width' MYAPP.HeaderCollectionReusableView:0x7fe602031c40.width == 1093 (active)>"
)
I understand that the issue is in the imageView within the Header but not sure exactly what it is.
These are the constraints for the image in the header view:
episodeImageView.anchor(top: topAnchor, leading: leadingAnchor, bottom: nil, trailing: trailingAnchor, size: .init(width: width, height: 0))
episodeImageView.heightAnchor.constraint(equalTo: episodeImageView.widthAnchor, multiplier: 0.65).isActive = true
I'm using the following extension for anchoring:
extension UIView {
var width: CGFloat {
return frame.size.width
}
var height: CGFloat {
return frame.size.height
}
var left: CGFloat {
return frame.origin.x
}
var right: CGFloat {
return left + width
}
var top: CGFloat {
return frame.origin.y
}
var bottom: CGFloat {
return top + height
}
func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) {
translatesAutoresizingMaskIntoConstraints = false
if let top = top {
topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true
}
if let leading = leading {
leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true
}
if let bottom = bottom {
bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom).isActive = true
}
if let trailing = trailing {
trailingAnchor.constraint(equalTo: trailing, constant: -padding.right).isActive = true
}
if size.width != 0 {
widthAnchor.constraint(equalToConstant: size.width).isActive = true
}
if size.height != 0 {
heightAnchor.constraint(equalToConstant: size.height).isActive = true
}
}
}
And these are the constraints for the collection view:
private func setConstraints() {
var devWidth: CGFloat = 0.0
if UIDevice.current.orientation.isLandscape {
devWidth = view.width * 0.8
} else {
devWidth = view.height * 0.8
}
leadingCVAnchor = collectionView?.leadingAnchor.constraint(equalTo: view.leadingAnchor)
trailingCVAnchor = collectionView?.trailingAnchor.constraint(equalTo: view.trailingAnchor)
centerCVAnchor = collectionView?.centerXAnchor.constraint(equalTo: view.centerXAnchor)
widthCVAnchor = collectionView?.widthAnchor.constraint(equalToConstant: devWidth)
collectionView?.translatesAutoresizingMaskIntoConstraints = false
collectionView?.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
collectionView?.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
leadingCVAnchor?.isActive = true
trailingCVAnchor?.isActive = true
if UIDevice.current.userInterfaceIdiom == .pad {
if UIDevice.current.orientation.isLandscape {
centerCVAnchor?.isActive = true
widthCVAnchor?.isActive = true
leadingCVAnchor?.isActive = false
trailingCVAnchor?.isActive = false
} else {
leadingCVAnchor?.isActive = true
trailingCVAnchor?.isActive = true
}
} else {
leadingCVAnchor?.isActive = true
trailingCVAnchor?.isActive = true
}
}
with this override to viewWillTransition:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.userInterfaceIdiom == .pad {
if UIDevice.current.orientation.isLandscape {
print("Orientation Landscape")
leadingCVAnchor?.isActive = false
trailingCVAnchor?.isActive = false
widthCVAnchor?.isActive = true
centerCVAnchor?.isActive = true
} else {
print("Orientation Portrait")
leadingCVAnchor?.isActive = true
trailingCVAnchor?.isActive = true
widthCVAnchor?.isActive = false
centerCVAnchor?.isActive = false
}
}
}
This project does not use storyboards, everything is done in code.
I'm fairly new with constraints so not sure where to fix the problem or how to interpret the NSLayoutConstraint warnings.
How can I solve this constraint issue?