冲突约束(不存在)(Swift 4)
Posted
技术标签:
【中文标题】冲突约束(不存在)(Swift 4)【英文标题】:Conflicting Constraints (that do not exist) (Swift 4) 【发布时间】:2020-10-10 18:34:54 【问题描述】:当手机旋转时,我正在重新排列三个视图:
我设置约束如下:
var narrowConstraints: [NSLayoutConstraint] = []
var wideConstraints: [NSLayoutConstraint] = []
func setConstraints1()
let cv1Height: CGFloat = 325
let cv3Height: CGFloat = 125
cv1.translatesAutoresizingMaskIntoConstraints = false
cv2.translatesAutoresizingMaskIntoConstraints = false
cv3.translatesAutoresizingMaskIntoConstraints = false
let g = view.safeAreaLayoutGuide
// wh
narrowConstraints = [
// set cv1 height
cv1.heightAnchor.constraint(equalToConstant: cv1Height),
// lock top, left and right to safe area
cv1.topAnchor.constraint(equalTo: g.topAnchor),
cv1.leadingAnchor.constraint(equalTo: g.leadingAnchor),
cv1.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// lock left and right to safe area
cv2.leadingAnchor.constraint(equalTo: g.leadingAnchor),
cv2.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// lock top of cv2 to bottom of cv1
cv2.topAnchor.constraint(equalTo: cv1.bottomAnchor),
// lock bottom of cv2 to top of cv3
cv2.bottomAnchor.constraint(equalTo: cv3.topAnchor),
// set cv3 height
cv3.heightAnchor.constraint(equalToConstant: cv3Height),
// lock left, right and bottom to safe area
cv3.leadingAnchor.constraint(equalTo: g.leadingAnchor),
cv3.trailingAnchor.constraint(equalTo: g.trailingAnchor),
cv3.bottomAnchor.constraint(equalTo: g.bottomAnchor),
]
wideConstraints = [
// lock top, bottom, and left to safe area
cv1.topAnchor.constraint(equalTo: g.topAnchor),
cv1.bottomAnchor.constraint(equalTo: g.bottomAnchor),
cv1.leadingAnchor.constraint(equalTo: g.leadingAnchor),
// lock right side of cv1 to left side of cv2
cv1.trailingAnchor.constraint(equalTo: cv2.leadingAnchor),
// lock right side of cv2 to safe area
cv2.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// lock top of cv2 to safe area
cv2.topAnchor.constraint(equalTo: g.topAnchor),
// lock bottom of cv2 to top of cv3
cv2.bottomAnchor.constraint(equalTo: cv3.topAnchor),
// set cv3 height
cv3.heightAnchor.constraint(equalToConstant: cv3Height),
// lock bottom and right side of cv3 to safe area
cv3.trailingAnchor.constraint(equalTo: g.trailingAnchor),
cv3.bottomAnchor.constraint(equalTo: g.bottomAnchor),
// make them all equal widths
cv2.widthAnchor.constraint(equalTo: cv1.widthAnchor),
cv3.widthAnchor.constraint(equalTo: cv2.widthAnchor),
]
if view.frame.width > view.frame.height
// if landscape
NSLayoutConstraint.deactivate(narrowConstraints)
NSLayoutConstraint.activate(wideConstraints)
else // portrait
NSLayoutConstraint.deactivate(wideConstraints)
NSLayoutConstraint.activate(narrowConstraints)
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: _ in
if size.width > size.height
// we're transitioning to wider than tall
NSLayoutConstraint.deactivate(self.narrowConstraints)
NSLayoutConstraint.activate(self.wideConstraints)
else
// we're transitioning to taller than wide
NSLayoutConstraint.deactivate(self.wideConstraints)
NSLayoutConstraint.activate(self.narrowConstraints)
, completion:
_ in
// if you want to do something after the transition
//self.cv2.setNeedsDisplay()
)
一切似乎都运行良好 - 除了以下错误消息:
2020-10-16 14:33:57.364778-0600 ViewPositions2[38358:6108060] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x6000033a9130 UIView:0x7fb41950ad90.height == 325 (active)>",
"<NSLayoutConstraint:0x6000033aa800 UIView:0x7fb41950ad90.top == UILayoutGuide:0x6000029bcb60'UIViewSafeAreaLayoutGuide'.top (active)>",
"<NSLayoutConstraint:0x6000033aa3f0 V:[UIView:0x7fb41950ad90]-(0)-[UIView:0x7fb41950dec0] (active)>",
"<NSLayoutConstraint:0x6000033a9ea0 UIView:0x7fb41950dec0.bottom == UIView:0x7fb41950e8f0.top (active)>",
"<NSLayoutConstraint:0x6000033a9c70 UIView:0x7fb41950e8f0.height == 125 (active)>",
"<NSLayoutConstraint:0x6000033aa2b0 UIView:0x7fb41950e8f0.bottom == UILayoutGuide:0x6000029bcb60'UIViewSafeAreaLayoutGuide'.bottom (active)>",
"<NSLayoutConstraint:0x60000339ff20 'UIView-Encapsulated-Layout-Height' UIView:0x7fb41950f1c0.height == 375 (active)>",
"<NSLayoutConstraint:0x60000339b840 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x6000029bcb60'UIViewSafeAreaLayoutGuide']-(0)-| (active, names: '|':UIView:0x7fb41950f1c0 )>",
"<NSLayoutConstraint:0x60000339b7a0 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x6000029bcb60'UIViewSafeAreaLayoutGuide'] (active, names: '|':UIView:0x7fb41950f1c0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000033a9130 UIView:0x7fb41950ad90.height == 325 (active)>
经过反复试验,我发现如果cv1Height
和cv2Height
的总和超过375(横向视图高度),则会出现此错误消息。
但是,我不仅在横屏时停用了narrowConstraints
,而且在横屏时cv1
永远不会在cv3
之上!
为什么会发生这种冲突?怎么预防???
【问题讨论】:
【参考方案1】:冲突是由于过渡期间状态栏的出现引起的。虽然您可以忽略警告(它不会影响应用的操作或外观),但可以通过降低纵向配置中 cv1
高度约束的优先级来消除警告:
let h1 = cv1.heightAnchor.constraint(equalToConstant: cv1Height)
h1.priority = .defaultHigh
narrowConstraints = [
// set cv1 height
h1,
// lock top, left and right to safe area
cv1.topAnchor.constraint(equalTo: g.topAnchor),
cv1.leadingAnchor.constraint(equalTo: g.leadingAnchor),
cv1.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// lock left and right to safe area
cv2.leadingAnchor.constraint(equalTo: g.leadingAnchor),
cv2.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// lock top of cv2 to bottom of cv1
cv2.topAnchor.constraint(equalTo: cv1.bottomAnchor),
// lock bottom of cv2 to top of cv3
cv2.bottomAnchor.constraint(equalTo: cv3.topAnchor),
// set cv3 height
cv3.heightAnchor.constraint(equalToConstant: cv3Height),
// lock left, right and bottom to safe area
cv3.leadingAnchor.constraint(equalTo: g.leadingAnchor),
cv3.trailingAnchor.constraint(equalTo: g.trailingAnchor),
cv3.bottomAnchor.constraint(equalTo: g.bottomAnchor),
]
【讨论】:
令人着迷,船长。我们应该将其视为错误吗? 也许这只是 AutoLayout 的迷人特质之一? 好吧,我建议 OP 应该报告它。就像那些关于警报和工具栏的虚假冲突报告一样,令人抓狂 是的。创建minimal reproducible example 并不难,值得举报 @Paulw11 - 我刚刚发布了另一个似乎相关的问题:***.com/questions/64539800/… 这也是一个错误吗?以上是关于冲突约束(不存在)(Swift 4)的主要内容,如果未能解决你的问题,请参考以下文章