2013-10-31 59 views
16

我有一個表格視圖和一個單元格。單元格包含三個標籤:標題標籤和兩個彼此低於一個的標籤。有時,如果它們不包含數據並將「標題標籤」的「頂部空間到容器」更改爲「將Y中央到容器」更改,我需要在下面隱藏這兩個標籤。當然,當兩個標籤包含數據時,還原約束條件。這是一個簡單的演示項目的截圖只是爲了顯示這個想法:如何在運行時更改標籤約束?

enter image description here

UPDATE最大麥克勞德回答指出正確的方向。訣竅是在隱藏第一個和第二個標籤時將標題標籤向下推。因此,我們需要將底部空間設置爲第一個和第二個標籤的容器視圖,而不是爲容器標籤的容器視圖創建頂部空間。通過高度出口(第一和第二標籤的高度限制)並將它們的常數值設置爲零(並且在取消隱藏時設置後退值)來隱藏/取消隱藏。我也上傳了source code example to Github

回答

32

選擇標題標籤,和下一個標籤,並添加一個新的垂直空間的限制體現他們之間的差距。接下來,將標題標籤Top space刪除到容器約束。也許你已經有了這個(不能從屏幕抓看不到)。如果你這樣做,那很好。

現在,爲每個較低標籤創建兩個高度約束。 IBOutlet那些你的班級。

然後,通過將每個高度限制的constant設置爲0.f,只要需要,就隱藏這兩個較低的標籤。

這將使它們不可見並降低上面的標題標籤,以便它現在在容器中垂直居中Y.

將再次通過這些步驟(太長了評論!)。順序與IB有關,首先必須添加一個新的約束,然後才能刪除舊的約束。暫時你會有一個多餘的約束。這是因爲IB不會含糊不清。所以,首先添加新的垂直空間約束。這將定義上標籤的Y位置。然後,從上面的標籤刪除多餘的垂直空間到容器約束。現在該標籤將被定位爲使用相對於較低標籤的垂直空間。接下來,使用IBOutlet爲每個較低標籤添加高度約束並鏈接到該類。另外一件事,實際上你需要將較低的標籤限制在具有底部空間限制的容器中。當它們的高度減少到零時,它們將消失,並且上部標籤將移動到較低位置以呈現Y中心位置。

要恢復,只需設置constant回到原來的值。

這比添加/移除的約束,這是一個重量級操作的更好的方法。請注意,您可能希望將兩個較低的標籤添加到「容器」視圖,以便它們可以作爲一個顯示/隱藏。此外,它會整理代碼,因爲您確實希望垂直空間位於上層標籤和下層標籤之間,而不僅僅是一個。

參見我的答案AutoLayout with hidden UIViews?

+0

你是什麼意思「添加一個新的約束,使標題標籤有一個垂直的差距」。應該是什麼樣的約束?我已經通過垂直空間約束來標記帶有標題標籤的較低標籤。 – Centurion

+0

如果我刪除「頂部空間到容器」的約束,然後IB顯示錯誤與「需要約束的Y位置」 – Centurion

+0

是啊,首先你需要給它新的約束,然後添加 - 現在superflous - 舊的。 IB不允許歧義 –

-3

很少有人能夠容易理解,並提供一些實際操作的示例,以便了解Apple文檔,但這是規則中例外的確切情況。

我個人發現這個文件很容易理解,而且很清楚。成爲一個自動佈局大師的時間,最好的辦法:)

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutinCode/AutoLayoutinCode.html

基本上,運行時的意思是「編程」。

所以回答你的問題就出在這裏:

https://stackoverflow.com/a/12623006/517119

+0

蘋果鏈路中斷。請考慮更新它。 –

0

我做得非常喜歡這個自己。所以爲兩個標籤添加一個寬度約束。您可以在應用約束條件時更改常數值 - 只需保留一個引用即可。在我的情況下,我有一個數組,我把我想要改變的約束。

當你要隱藏的標籤時,c值更改爲0 - 你可以在一個動畫塊做到這一點。顯示更改值。

你也可以讓上面的空間等於底部空間的寬度,所以當視圖隱藏或顯示您保持中心項目「組」。

請注意,您可以添加或刪除限制太多,但它更昂貴的iOS處理。

5

將想要隱藏的標籤放入視圖中,一旦所有東西都具有正確的佈局約束,向容器視圖添加高度約束並將約束連接到IBOutlet屬性。

確保您的屬性strong

代碼

喲只需要恆定的設置爲0,並激活它,壽隱藏的內容,或取消其展示的內容。 這比用不斷的價值修復它更好。 之後別忘了打電話layoutIfNeeded

@property (strong, nonatomic) IBOutlet UIView *myContainer; 
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *myContainerHeight; //should be strong!! 

-(void) showContainer 
{ 
    self.myContainerHeight.active = NO; 
    self.myContainer.hidden = NO; 
    [self.view layoutIfNeeded]; 
} 
-(void) hideContainer 
{ 
    self.myContainerHeight.active = YES; 
    self.myContainerHeight.constant = 0.0f; 
    self.myContainer.hidden = YES; 
    [self.view layoutIfNeeded]; 
} 

一旦你有你的設置,你可以通過你的約束背部設置爲0,然後到原始值測試它在IntefaceBuilder。不要忘記檢查其他約束優先級,以便在隱藏時根本不存在衝突。其他測試方法是將其設置爲0並將優先級設置爲0,但是,您不應該忘記將其恢復到最高優先級。

+0

令人敬畏的答案...我知道我們可以保留約束的出口n有一個佔位符約束..但現在知道我們可以激活約束 –

+0

我很高興你找到我的答案有用,謝謝。 –