2014-09-02 274 views
3

我已經完全通過添加子視圖和約束(使用CocoaPod PureLayout)在代碼中創建了我的視圖控制器的視圖。它實際上看起來/功能到底如何我想要它,但xcode大聲對我說,其中一個約束是錯誤的,它將其刪除。我怎樣才能知道哪些UIViews的壞約束被附加到?我有很多子視圖,我無法從上下文中找出它。當在界面構建器中使用約束時,可以命名UIView並將其打印到調試控制檯 - 但我無法找到通過代碼實現此目的的方法。調試編程自動佈局約束

縱觀蘋果文檔:https://developer.apple.com/library/ios/documentation/userexperience/conceptual/AutolayoutPG/ResolvingIssues/ResolvingIssues.html#//apple_ref/doc/uid/TP40010853-CH17-SW14

他們說: 「這可能是顯而易見的,其觀點有問題;如果不是,你可能會發現它有助於使用的NSView方法_subtreeDescription創建一個文本視圖層次的描述

重要提示:_subtreeDescription方法是不公開的API,但它是,允許用於調試的目的」

難道這就是我要找的?我如何使用私人API?

+0

您可以調用'_subtreeDescription'通過增加對'UIView'臨時類聲明的方法 - 讓編譯器不會抱怨 - 然後就調用它。 – ravron 2014-09-02 13:59:24

+0

如果可能,你能舉一個例子嗎?我不確定我是否遵守。 – dMurdZ 2014-09-02 14:03:21

+0

在進一步調查中,'_subtreeDescription'只能在NSView(OS X)上使用,而不能在UIView中使用,所以這種方法不會對你有所幫助。您可能需要仔細查看日誌消息以查找相關視圖的內存地址。然後,嘗試通過在適當的地方暫停執行來檢查您的子視圖的地址來找到該視圖。或者,使用lldb遞歸地詢問違規視圖的超級視圖。這會讓你追溯它的祖先。 – ravron 2014-09-02 14:11:30

回答

9

從iOS 8 SDK開始,現在有identifier property on NSLayoutConstraint。請注意,此屬性自iOS 7起私人存在(僅適用於Apple),但現在已在iOS 8中公開,即使在iOS 7上運行時也允許使用該屬性。

使用此屬性可以輕鬆地爲您的約束設置一個獨特的簡短描述來幫助調試。例如,使用:

NSLayoutConstraint *constraint = [label autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:imageView]; 
constraint.identifier = @"Label Left Padding"; 

// ...or using PureLayout v2.0+: 
[[label autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:imageView] autoIdentify:@"Label Left Padding"]; 

// PureLayout v2.0+ also supports a block-based version to set an identifier to many constraints at once: 
[UIView autoSetIdentifer:@"Constraints to position image view" forConstraints:^{ 
    // ...a bunch of PureLayout API calls here that create constraints... 
}]; 

然後,你會看到這個標識旁邊控制檯約束打印,如果有一個約束的例外。

另一個方便的調試工具:

蘋果對UIView的命名UIConstraintBasedLayoutDebugging一個非常方便的類別(在UIView.h聲明),其中包括一個方法:

- (NSArray *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis; 

您可以調用此方法在任何視圖,傳遞水平軸或垂直軸(因爲每個軸的約束都是獨立的),並獲取影響沿該軸的位置和大小的所有約束的列表。請注意,Apple表示這應該只用於調試 - 絕不會發布使用此API的代碼!

+1

真棒,謝謝你。並感謝PureLayout,我發現它非常有用! – dMurdZ 2014-09-18 13:38:09

3

UIWindow還具有一個私有實例方法_autolayoutTrace來轉儲顯示整個視圖層次結構的字符串,其中包括不明確的視圖。在看到約束異常之後設置斷點後,只需在控制檯中使用它即可。您還可以使用符號斷點「UIViewAlertForUnsatisfiableConstraints」來捕獲任何自動佈局異常。

退房Facebook的鑿過:https://github.com/facebook/chisel