简体   繁体   English

iOS 11:“无法同时满足约束”

[英]iOS 11: “Unable to simultaneously satisfy constraints”

always running into the FoodTracker tutorial;总是遇到 FoodTracker教程; following this step: "Implement a custom control"遵循此步骤:“实现自定义控件”

https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/ImplementingACustomControl.html#//apple_ref/doc/uid/TP40015214-CH19-SW1 https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/ImplementingACustomControl.html#//apple_ref/doc/uid/TP40015214-CH19-SW1

and when executing the first checkpoint the simulator shows a red rectangle instead of a square as indicated on the tutorial;并且在执行第一个检查点时,模拟器显示红色矩形而不是教程中指示的正方形; on the debug pane I get:在调试窗格中,我得到:

2018-02-09 11:19:42.130595+0100 FoodTracker[7439:80369] [MC] Lazy loading NSBundle MobileCoreServices.framework  
2018-02-09 11:19:42.131628+0100 FoodTracker[7439:80369] [MC] Loaded MobileCoreServices.framework  
2018-02-09 11:19:42.165143+0100 FoodTracker[7439:80369] [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:0x60400028a3c0 UIButton:0x7f8a0bd0e330.width == 44   (active)>",  
    "<NSLayoutConstraint:0x60400028cda0 'UISV-canvas-connection' FoodTracker.RatingControl:0x7f8a0bd08890.leading == UIButton:0x7f8a0bd0e330.leading   (active)>",  
    "<NSLayoutConstraint:0x60400028ce40 'UISV-canvas-connection' H:[UIButton:0x7f8a0bd0e330]-(0)-|   (active, names: '|':FoodTracker.RatingControl:0x7f8a0bd08890 )>",  
    "<NSLayoutConstraint:0x60400028c940 'UIView-Encapsulated-Layout-Width' FoodTracker.RatingControl:0x7f8a0bd08890.width == 200   (active)>"  
)  

Will attempt to recover by breaking constraint  
<NSLayoutConstraint:0x60400028a3c0 UIButton:0x7f8a0bd0e330.width == 44   (active)>  

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.  
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.  
2018-02-09 11:19:42.165949+0100 FoodTracker[7439:80369] [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:0x60400028a370 UIButton:0x7f8a0bd0e330.height == 44   (active)>",  
    "<NSLayoutConstraint:0x60400028a320 'UISV-canvas-connection' FoodTracker.RatingControl:0x7f8a0bd08890.top == UIButton:0x7f8a0bd0e330.top   (active)>",  
    "<NSLayoutConstraint:0x60400028cf30 'UISV-canvas-connection' V:[UIButton:0x7f8a0bd0e330]-(0)-|   (active, names: '|':FoodTracker.RatingControl:0x7f8a0bd08890 )>",  
    "<NSLayoutConstraint:0x60400028c990 'UIView-Encapsulated-Layout-Height' FoodTracker.RatingControl:0x7f8a0bd08890.height == 110   (active)>"  
)  

Will attempt to recover by breaking constraint  
<NSLayoutConstraint:0x60400028a370 UIButton:0x7f8a0bd0e330.height == 44   (active)>  

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.  
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.  

I think that something is changed when programmatically create the button and applying custom constraints here: (I'm working with Swift and Xcode 9)我认为以编程方式创建按钮并在此处应用自定义约束时会发生一些变化:(我正在使用 Swift 和 Xcode 9)

// Add constraints  
button.translatesAutoresizingMaskIntoConstraints = false  
button.heightAnchor.constraint(equalToConstant: 44.0).isActive = true  
button.widthAnchor.constraint(equalToConstant: 44.0).isActive = true  

Any hint to solve the issue is welcome.欢迎任何解决问题的提示。

Please note that I'm building a custom control... All the notes I've found googling around seems not to be applicables.请注意,我正在构建一个自定义控件......我在谷歌上搜索的所有注释似乎都不适用。

Epilogue结语

The issue disappeared himself.这个问题自己消失了。

Proceeding with the excercise, Xcode IDE underlined some critical points on the view design where I was invited to "click on the icon" to fix;继续练习,Xcode IDE 强调了视图设计的一些关键点,我被邀请“单击图标”进行修复; one of this issue was tied to the conflicting contrains.这个问题之一与相互冲突的限制有关。

As suggested by #DonMag, the RatingControl class has to be marked as @IBDesignable (this decorator will be added later on the excercise) to let Xcode immediately view the final result of the custom control.正如#DonMag 所建议的那样,RatingControl 类必须标记为@IBDesignable(此装饰器将在稍后的练习中添加),以便让 Xcode 立即查看自定义控件的最终结果。 Almost: The stars doesn't appeared and the control doesn't automatically scale adding stars to the control property.几乎:星星不会出现并且控件不会自动缩放将星星添加到控件属性。 This until I closed, opened again and rebuilt several times the whole project.直到我关闭,再次打开并多次重建整个项目。

Differences on tutorial (written for Swift 3.2) and actual Xcode (default project opened in Swift 4 applies.教程(为 Swift 3.2 编写)和实际 Xcode(在 Swift 4 中打开的默认项目适用)的差异。

It's my idea that Apple has to update it's own online documentation to avoid people loose their mind trying to figure out why things doesn't work like expected.我的想法是 Apple 必须更新它自己的在线文档,以避免人们在试图弄清楚为什么事情不像预期的那样工作时失去理智。

Ignore my first two comments...忽略我的前两个评论...

In that tutorial, you are adding the custom ratingControl as an arranged subview of a Vertical Stack View.在该教程中,您将自定义ratingControl添加为垂直堆栈视图的排列子视图。 That's why no constraints are needed.这就是为什么不需要约束的原因。

The key is making the class @IBDesignable - that allows Interface Builder and the Auto-Layout engine to use the class' intrinsic size to properly size / position / display it.关键是使类@IBDesignable - 允许界面生成器和自动布局引擎使用类的固有大小来正确调整大小/位置/显示它。

(Just a little surprising it's not noted in the tutorial.) (只是有点令人惊讶,它没有在教程中注明。)

I had the same issue.我有同样的问题。 Also, the red squares appeared bigger than shown in the tutorial.此外,红色方块看起来比教程中显示的要大。 For the red squares to accept the constraints of size 44, I had to ensure the RatingControl was positioned inside the stack view, not below.对于红色方块接受尺寸44的约束,我不得不确保RatingControl被定位堆栈视图,而不是下方。

I'm attaching images for clarification of what I mean by "inside" the stack view.我附上了图像以澄清我所说的“内部”堆栈视图的含义。

error reproduced, please note red rectangle outside the stack view hierarchy错误重现,请注意堆栈视图层次结构外的红色矩形

error fixed, the red rectangle is inside the stack view hierarchy on the left错误已修复,红色矩形位于左侧的堆栈视图层次结构内

The issue is happening because of the total width of all sub views is not equal to the width of StackView.问题的发生是因为所有子视图的总宽度不等于 StackView 的宽度。

Using this calculation can fix the problem:使用此计算可以解决问题:

let width = (self.frame.width - self.spacing * CGFloat(starCount-1))/CGFloat(starCount)
let height = self.frame.height

............ ………………

for _ in 0..<starCount {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = UIColor.red
        button.heightAnchor.constraint(equalToConstant: height).isActive = true
        button.widthAnchor.constraint(equalToConstant: width).isActive = true
        button.addTarget(self, action: #selector(RatingControl.ratingButtonTapped(button:)), for: .touchUpInside)
        addArrangedSubview(button)
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM