2014-01-08 54 views
4

我一直在代碼中完成我的用戶界面,但已決定我應該爲當前項目使用故事板和自動佈局。一切都進展順利,直到我建立了一個擁有大量層次結構和一些視圖的大約50個視圖的複雜場景。在代碼中修改故事板自動佈局約束的最佳做法?

問題是我的自動佈局在某些設備和方向上變得混亂。我發現使用IB來嘗試修復幾十(幾百?)個約束或追蹤問題並解決它們是非常具有挑戰性的。情況是這樣的,我沒有得到錯誤或警告,有時只是一些不愉快的佈局。而IB可能會帶來一些痛苦,包括你需要做的所有點擊和改變設置來追蹤約束信息,更不用說全面瞭解它們如何與場景相關。

我剛剛花了一天時間就自動佈局和約束閱讀文檔和背景材料,它似乎我的最好的解決辦法是使用可視化格式代碼,以指定的約束,並創建一些自定義代碼,以幫助。但是,我似乎無法找到關於如何從IB轉換到代碼的任何事情。

具體而言,我是否應該清除所有IB限制並全部手動完成,還是有可能具有選擇性?我問,因爲我有一些視圖組包含視圖的內容視圖有一個完美的佈局。

其次,我最好把我的代碼放在哪裏?我想共存故事板,只想有選擇地修改一些複雜的場景。是視圖控制器的viewWillAppear:修改或刪除/添加它控制的視圖的約束的正確位置?

+0

只是一個快速更新,我還沒有解決這個問題。我做了很多自由職業的工作,不得不稍稍轉移一下,但希望能在一天左右再回來,並嘗試不同的建議。感謝Ron和Eagle11的建議,這兩者似乎都非常好。 –

回答

5

對不起,如此久以至於在其他項目被侵入時回到這個位置。

我不得不做大量的重構來簡化我的場景,這樣的自動佈局可以做正確的事情,可是我並不完全滿意的結果。這個問題似乎是IB很難用於很多物品,而且自動佈局是非常複雜的。

隨着中說,到目前爲止,我見過的最好的結果是從這篇文章由Justin德里斯科爾得出:http://themainthread.com/blog/2014/02/building-a-universal-app.html

他主張建立自定義視圖封裝了可重用的UI組件。我採取了這種方法,但已經將這個想法擴展到了捆綁相關組件,這些組件在佈局更改時不會非常不同。例如,我有一個帶有按鈕和兩個標籤的進度條,所以即使我沒有將它們重用爲一個組,它們需要相鄰並且在概念上是相關的,因此我爲它們定製了自動處理自動化視圖賈斯汀建議佈局。

我現在正在採取的方法,每個級別的自動佈局應該只有少數元素。如果一個級別太複雜,我會在自定義視圖中捆綁一些相關的項目,並在該新視圖中推入一些自動佈局。到目前爲止它還不算太壞。

+0

我將選擇這個作爲最佳答案,因爲賈斯汀的解決方案給了我最大的控制權並造成了最少的問題。 Ron和Eagle11都給出了很好的建議,讓我得到了這個答案,我希望我可以檢查所有三個答案,但這是不可能的。謝謝你們。 –

2

使用多個視圖時,自動佈局可能會非常棘手。我使用了類似複雜的視圖結構,並且我發現最好嘗試在代碼或IB中保留所有約束。現在我們將他們保留在IB中。我們將約束移入代碼的唯一時間是當我們支持不同的屏幕大小時,我們需要修改一個約束,使視圖正常工作。我一直修改viewDidLoad自己的約束。

當某樣東西弄亂了我幾乎總是有核彈攻擊所有在該視圖上的約束,並重新開始。它很糟糕,但通常比追蹤問題更快。我們做的一件事就是處理這種事情更容易,就是使用.xibs和你的故事板。這樣,每個視圖都可以處理它自己的佈局,並且可以將其拖入坐在故事板中的視圖中。

+0

我可以相信,「全部或全部」是正確的,因爲錯誤的可能性似乎很高。 你能解釋你如何使用xibs嗎?你讓一個替換整個場景並從代碼中加載它嗎? –

+0

嗯,我相信我們並不總是以最好的方式去做,但我們找到了一種爲我們工作的方法。 我們嘗試創建故事板中的所有層次結構,並根據情況在故事板中創建內容。在我們的一些項目中,我們有幾個故事板,因爲這個項目非常大。正因爲如此,我們把很多我們的意見分解成xibs。我們在代碼中加載xib並將其設置爲視圖控制器中的視圖。 – Eagle11

+0

順便說一句,自動佈局在處理所有奇怪的垃圾一週後變得更容易使用。一旦你真正瞭解它,它可以很容易地使用。即使在大型項目上。 – Eagle11

9

連接一個IBOutlet的NSLayoutConstraint你希望能夠在情節提要/ XIB文件到您的控制器/視圖類進行修改。

一旦你的佈局對象連接,您可以修改.constant屬性和動畫的觀點:

[self.containerView layoutIfNeeded]; //make sure all layout operations are done 
self.containerViewBottomLayoutConstraint.constant = 200.0; //change the layout 
[UIView animateWithDuration:duration animations:^{ 
    [self.containerView layoutIfNeeded]; //animate the changes 
}]; 

更新:您可以在viewDidLoad中,awakeFromNib,viewDidAppear添加修改代碼,或基於事件。這真的取決於你的意圖。

+0

我想我有太多的限制來將它們連接到IBOutlets,但是如果我可以減少對小集的更改,這可能會起作用。我需要稍微研究一下這個問題,但是如果所有的約束條件都是在代碼開始的時候,看起來像很多工作可能會更容易。 –

+0

我的意圖是修復約束,以便它們可以在所有設備配置中工作。如果我可以幫忙的話,我不打算製作動畫或動態改變它們。我認爲viewWillAppear可能是建立它們的地方,但是你的評論讓我懷疑這是否是正確的地方。在使用Storyboard時,awakeFromNib是否會觸發它,並且它是刪除/添加約束的正確位置? viewDidLoad太遲了?當用戶看到它時,它會導致場景改變嗎? –

+0

awakeFromNib確實在視圖(控制器)從故事板反序列化時調用:更多信息在這裏:https://developer.apple.com/library/ios/documentation/uikit/reference/NSObject_UIKitAdditions/Introduction/Introduction.html#//apple_ref/occ/instm/NSObject/awakeFromNib 我會在viewDidLoad或awakeFromNib中設置約束,具體取決於您在didLoad中執行其他視圖層次結構修改的意圖。實際設置故事板中的所有約束有什麼問題?嘗試新的beta xcode,它有一些改進。還檢查了自動佈局WWDC13會議.. – Ron

相關問題