2014-09-24 36 views
0

我試圖通過編程方式使用自動佈局顯示錶格單元格中的內容。我想的內容,以顯示如下:自動佈局 - 複雜的約束條件

[標題]
[圖像] [日期]
[文本的長字符串,跨越表的寬度,最大的兩行]

我的代碼如下所示:

-(NSArray *)constraints { 
    NSMutableArray * constraints = [[NSMutableArray alloc]init]; 
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_titleLabel, _descriptionLabel, _dateLabel, _ratingBubbleView); 

    NSDictionary *metrics = @{@"padding":@(kPadding)}; 

    NSString *const kVertical = @"V:|-(>=0,<=padding)-[_titleLabel]-(<=padding)-[_ratingBubbleView]-(<=padding)-[_descriptionLabel]-(>=0,<=padding)-|"; 
    NSString *const kVertical2 = @"V:|-(>=0,<=padding)-[_titleLabel]-(<=padding)-[_dateLabel]-(<=padding)-[_descriptionLabel]-(>=0,<=padding)-|"; 
    NSString *const kHorizontalDescriptionLabel = @"H:|-padding-[_descriptionLabel]-padding-|"; 
    NSString *const kHorizontalTitleLabel = @"H:|-padding-[_titleLabel]"; 
    NSString *const kHorizontalDateLabel = @"H:|-padding-[_ratingBubbleView]-padding-[_dateLabel]"; 

    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kVertical options:0 metrics:metrics views:viewsDictionary]]; 
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kVertical2 options:0 metrics:metrics views:viewsDictionary]]; 
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalDescriptionLabel options:0 metrics:metrics views:viewsDictionary]]; 
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalTitleLabel options:0 metrics:metrics views:viewsDictionary]]; 
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalDateLabel options:0 metrics:metrics views:viewsDictionary]]; 

    return constraints; 
} 

這是結果: This is the result

+1

爲什麼'(> = 0,<= padding)'?你可能會添加一個你試圖實現的佈局的圖片(或草圖)嗎?僅僅通過觀察約束就很難理解你想要完成什麼。另外,什麼是不正確的顯示?你說這是不正確的,但你沒有說它實際上在做什麼。 – Fogmeister 2014-09-24 14:40:55

+1

這段代碼給了你什麼結果?具體而言,「圖片和日期顯示不正確」對於那些試圖幫助你的人沒有用處。 – rdelmar 2014-09-24 14:43:52

+0

@Fogmeister我更新了問題以顯示我的意思。感謝您指出了這一點。至於'(> = 0,<= padding)',我對於Objective-C和自動佈局還是很新的,而且這個由前面的開發人員負責這個項目。 – Matt 2014-09-24 14:48:48

回答

1

OK,我不會嘗試解決您的代碼。我只是要創建約束條件來實現佈局。我會在評論中提出思考過程。

首先得到一個不錯的垂直佈局會...

// I'm just using standard padding to make it easier to read. 
// Also, I'd avoid the variable padding stuff. Just set it to a fixed value. 
// i.e. ==padding not (>=0, <=padding). That's confusing to read and ambiguous. 
@"V:|-[titleLabel]-[ratingBubbleView]-[descriptionLabel]-|" 

然後通過層去了層添加水平的限制...

// constraint the trailing edge too. You never know if you'll get a stupidly 
// long title. You want to stop it colliding with the end of the screen. 
// use >= here. The label will try to take it's intrinsic content size 
// i.e. the smallest size to fit the text. Until it can't and then it will 
// break it's content size to keep your >= constraint. 
@"|-[titleLabel]->=20-|" 

// when adding this you need the option "NSLayoutFormatAlignAllBottom". 
@"|-[ratingBubbleView]-[dateLabel]->=20-|" 

@"|-[descriptionLabel]-|" 

儘量不要「過度約束「你的看法。在你的代碼中,你使用多個約束約束相同的視圖(如descriptionLabel到superview底部)。

一旦他們被定義,他們不需要再次定義。

再次,填充。只需使用padding而不是>=padding。 > = 20是否意味着20,21.5或320?佈局時不平等是不明確的。

此外,在我的約束中,我使用佈局選項將日期標籤的垂直軸限制在評分視圖中。即「與評級視圖保持一致」。而不是限制標題標籤和東西......這意味着我只需要定義該行界面的位置一次。

+0

謝謝,我會給它一個鏡頭。很難找到關於這個主題的好教程。 – Matt 2014-09-24 15:02:56

+0

@Matt同意。我發現的最好的(很長一段路)是Ray Wenderlich的書** iOS7 by Tutorials **。 AutoLayout的兩個完整章節。現在還有一個由Tutorials **提供的** iOS8。絕對值得購買。 – Fogmeister 2014-09-24 15:04:01

+0

很高興知道。不幸的是,這些新的限制使得顯示更加糟糕:[這是結果](http://i.imgur.com/h8P7mz2.png) – Matt 2014-09-24 15:05:38