【发布时间】:2021-08-27 16:51:51
【问题描述】:
我有一个 iOS 视图,它由一个带有 headerView 的 collectionView 组成。视图显示正常,但是当我旋转设备 (iPad) 时,标题元素会重复并且不正确。输出窗口显示如下
(
"<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)>"
)
我知道问题出在 Header 中的 imageView 中,但不确定到底是什么。
这些是标题视图中图像的约束:
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
我正在使用以下扩展进行锚定:
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
}
}
}
这些是集合视图的约束:
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
}
}
使用此覆盖到 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
}
}
}
这个项目不使用故事板,一切都是用代码完成的。
我对约束还很陌生,所以不确定在哪里解决问题或如何解释 NSLayoutConstraint 警告。
我该如何解决这个约束问题?
【问题讨论】:
标签: ios autolayout nslayoutconstraint