感謝http://useYourLoaf.com這個完整的解決方案:
快速的提示,我發現了埋在自動佈局一個WWDC 2015年會議的調試與約束問題的時候,可以幫助
如果您使用自動佈局時,您會熟悉Xcode在出現問題時吐出的日誌。爲了創建一個示例,我修改了my Stack View sample code併爲每個圖像添加了一個約束,使它們具有240的固定寬度(我們將會看到這不是一個好主意)。
![enter image description here](https://i.stack.imgur.com/icsFH.png)
,在普通寬度的觀點,如iPad的作品,但太寬了一個緊湊的寬度視圖,如iPhone的肖像。運行時的控制檯日誌閱讀起來並不好玩。跳過重複的文字你的問題的約束列表:
"<NSLayoutConstraint:0x7fc1ab520360 H:[UIImageView:0x7fc1ab532650(240)]>",
"<NSLayoutConstraint:0x7fc1ab536ef0 H:[UIImageView:0x7fc1ab537380(240)]>",
"<NSLayoutConstraint:0x7fc1ab545cc0 UIView:0x7fc1ab53d870.trailingMargin == UIStackView:0x7fc1ab53dae0.trailing>",
"<NSLayoutConstraint:0x7fc1ab545d10 UIStackView:0x7fc1ab53dae0.leading == UIView:0x7fc1ab53d870.leadingMargin>",
"<NSLayoutConstraint:0x7fc1ab54e240 'UISV-alignment' UIStackView:0x7fc1ab53dc70.centerX == UIStackView:0x7fc1ab531a10.centerX>",
"<NSLayoutConstraint:0x7fc1ab5167c0 'UISV-canvas-connection' UIStackView:0x7fc1ab531a10.leading == UIImageView:0x7fc1ab532650.leading>",
"<NSLayoutConstraint:0x7fc1ab54ad80 'UISV-canvas-connection' H:[UIImageView:0x7fc1ab537380]-(0)-| (Names: '|':UIStackView:0x7fc1ab531a10)>",
"<NSLayoutConstraint:0x7fc1ab5397d0 'UISV-canvas-connection' UIStackView:0x7fc1ab53dae0.leading == _UILayoutSpacer:0x7fc1ab54c3c0'UISV-alignment-spanner'.leading>",
"<NSLayoutConstraint:0x7fc1ab54a4a0 'UISV-canvas-connection' UIStackView:0x7fc1ab53dae0.centerX == UIStackView:0x7fc1ab53dc70.centerX>",
"<NSLayoutConstraint:0x7fc1ab54b110 'UISV-spacing' H:[UIImageView:0x7fc1ab532650]-(16)-[UIImageView:0x7fc1ab537380]>",
"<NSLayoutConstraint:0x7fc1ab548210 'UISV-spanning-boundary' _UILayoutSpacer:0x7fc1ab54c3c0'UISV-alignment-spanner'.leading <= UIStackView:0x7fc1ab531a10.leading>",
"<NSLayoutConstraint:0x7fc1ab551690 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fc1ab53d870(375)]>"
然後,日誌會告訴你這上面的約束已經決定分手:
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fc1ab536ef0 H:[UIImageView:0x7fc1ab537380(240)]>
日誌輸出採用了自動佈局視覺格式語言,但很難從系統創建的那些中挑選出我的約束。堆棧視圖的情況尤其如此,其設計意圖是爲您創建大部分約束條件。在這個微不足道的例子中,我知道我剛剛添加的固定寬度約束破壞了事情,但很難從日誌中看到更復雜的視圖,它越難獲得。
添加標識符的約束
日誌變得輕鬆了很多,如果你添加一個標識符每個約束理解(NSLayoutConstraint
以來的iOS 7已經有一個標識屬性)。在Interface Builder中找到的約束,並在屬性檢查器中添加的標識符(我使用$作爲前綴/後綴,使他們脫穎而出,在日誌中):
![enter image description here](https://i.stack.imgur.com/OZ2Hf.png)
更新18月 - 2015年:正如在註釋中指出的那樣,標識符只能在Xcode 7開始的Interface Builder中編輯。它在Xcode 6.4中不可見。
如果添加約束代碼:
constraint.identifier = "$HeartImageFixedWidth$"
這是棘手的,如果你正在使用的使用約束的陣列視覺格式的語言。例如,考慮銀行代碼片段來創建一個固定的寬度約束對心臟圖像視圖:
let heartWidth = NSLayoutConstraint.constraintsWithVisualFormat("[heart(240)]",
options:[], metrics:nil, views:viewsDictionary)
由於heartWidth是式[NSLayoutConstraint]的陣列設置標識符是更多一點的工作:
for constraint in heartWidth {
constraint.identifier = "$HeartImageFixedWidth$"
}
heartImage.addConstraints(heartWidth)
隨着我的限制,現在更容易找到他們在日誌文件中設置標識(見第4行):
"<NSLayoutConstraint:0x7f92a305aeb0 '$ContainerStackViewLeading$' UIStackView:0x7f92a3053220.leading == UIView:0x7f92a3052fb0.leadingMargin + 32>",
"<NSLayoutConstraint:0x7f92a305b340 '$ContainerStackViewTrailing$' UIView:0x7f92a3052fb0.trailingMargin == UIStackView:0x7f92a3053220.trailing + 32>",
"<NSLayoutConstraint:0x7f92a301cf20 '$HeartImageFixedWidth$' H:[UIImageView:0x7f92a3047ef0(240)]>",
"<NSLayoutConstraint:0x7f92a3009be0 '$StarImageFixedWidth$' H:[UIImageView:0x7f92a304d190(240)]>",
"<NSLayoutConstraint:0x7f92a3060cc0 'UISV-alignment' UIStackView:0x7f92a30533b0.centerX == UIStackView:0x7f92a30472b0.centerX>",
"<NSLayoutConstraint:0x7f92a301c590 'UISV-canvas-connection' UIStackView:0x7f92a30472b0.leading == UIImageView:0x7f92a3047ef0.leading>",
"<NSLayoutConstraint:0x7f92a305f680 'UISV-canvas-connection' H:[UIImageView:0x7f92a304d190]-(0)-| (Names: '|':UIStackView:0x7f92a30472b0)>",
"<NSLayoutConstraint:0x7f92a3064190 'UISV-canvas-connection' UIStackView:0x7f92a3053220.leading == _UILayoutSpacer:0x7f92a30608a0'UISV-alignment-spanner'.leading>",
"<NSLayoutConstraint:0x7f92a30415d0 'UISV-canvas-connection' UIStackView:0x7f92a3053220.centerX == UIStackView:0x7f92a30533b0.centerX>",
"<NSLayoutConstraint:0x7f92a305fa10 'UISV-spacing' H:[UIImageView:0x7f92a3047ef0]-(16)-[UIImageView:0x7f92a304d190]>",
"<NSLayoutConstraint:0x7f92a30508c0 'UISV-spanning-boundary' _UILayoutSpacer:0x7f92a30608a0'UISV-alignment-spanner'.leading <= UIStackView:0x7f92a30472b0.leading>",
"<NSLayoutConstraint:0x7f92a3063240 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7f92a3052fb0(375)]>"
還多CLE arer其約束的系統選擇了突破:
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f92a3009be0 '$StarImageFixedWidth$' H:[UIImageView:0x7f92a304d190(240)]>
添加標識符來限制也不是沒有努力,但它必須通過複雜的佈局的調試日誌進行排序下一次還清。
進一步閱讀
你如何設置這個觀點 - 在代碼中,IB還是兩者的結合?你可以更新你的問題,包括? – jrturton
可能的重複[獲取奇怪的錯誤談論約束在Xcode](http://stackoverflow.com/questions/11664115/getting-weird-error-talking-about-constraints-in-xcode) –
關於約束問題的答案已清除是在這裏:[無法同時滿足約束,將嘗試通過打破約束恢復](http://stackoverflow.com/q/11664115/2725435) –