首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不冲突的约束冲突(Swift)

不冲突的约束冲突(Swift)
EN

Stack Overflow用户
提问于 2020-10-17 06:04:19
回答 1查看 54关注 0票数 0

当手机旋转时,我会像这样重新排列三个视图:

我将约束设置如下:

代码语言:javascript
复制
    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()
        })
    }

除了下面的错误消息之外,所有这些看起来都工作得很好:

代码语言:javascript
复制
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)>

通过反复试验,我发现如果cv1Heightcv2Height的总和超过375 (横向视图高度),就会出现此错误消息。

但是,我不仅在景观中停用了narrowConstraints,而且在景观中cv1永远不会在cv3之上!

为什么会发生这种冲突?我该如何防止它?

EN

回答 1

Stack Overflow用户

发布于 2020-10-17 06:31:13

您可以将固定高度约束的优先级设置为低于.required的值

代码语言:javascript
复制
let fixedHeightConstraint = cv1.heightAnchor.constraint(equalToConstant: cv1Height)
fixedHeightConstraint.priority = .required - 1;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64396963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档