2010-07-28 62 views
9

默認情況下,UITableViewCell實例將標籤對textLabel/detailTextLabel放置在其父視圖的中心。我更喜歡將這一對對齊到單元格的頂部。我如何以編程方式做到這一點?UITableViewCell。如何以編程方式將textLabel與頂部對齊?

謝謝,
道格

+0

這是一個Iphone相關的問題? – 2010-07-28 11:44:24

+0

是的。 UITableViewCell和UITableView以及UITableViewController是iPhone OS獨有的。沒有? – dugla 2010-07-28 15:50:11

+1

那麼爲什麼不是標籤iPhone的問題?標記時請注意,以便其他人可以從您的問題中受益。 – 2010-08-02 03:30:54

回答

24

該文檔描述 - [UIView的layoutSubviews如

"Overridden by subclasses to layout subviews when layoutIfNeeded is invoked. The default implementation of this method does nothing." 

即描述並不詳細說明,不過是準確的。在這種情況下,該方法的行爲是佈置您的子視圖。只要設備方向改變,它就會被調用。無論何時調用-setNeedsLayout,它也將安排在稍後的調用中。因爲,UIView的實現什麼都不做(我假設UIControl也是這樣),你可以獲得完全的創意自由,讓你的UIView子類子視圖定位在你想要的任何位置。

在繼承一個UITableViewCell,你有兩個選擇嘗試:

  1. 覆蓋-layoutSubviews和
    1. 操縱的位置內置爲textLabel和-detailLabel意見。
  2. 覆蓋-viewDidLoad,
    1. 創建兩個自己UILabels提供文本和詳細的文字的,
    2. 將它們添加到self.contentView,並
    3. 覆蓋-layoutSubviews操縱的位置您的自定義的視圖的UILabel

related SO question中,RECO修正是爲了避免#1,操縱內置的textLabel和detailTextLabel。

更可靠的選擇將是做這樣的事情:


@interface MyTableViewCell : UITableViewCell { 
    UILabel *myTextLabel; 
    UILabel *myDetailTextLabel; 
} 
// ... property declarations 
@end 

@implementation MyTableViewCell 
@synthesize myTextLabel, myDetailTextLabel; 

- (id) initWithFrame: (CGRect)frame { 
    self = [super initWithFrame: frame]; 
    if (self) { 
     myTextLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; 
     [self.contentView addSubview: myTextLabel]; 

     myDetailTextLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; 
     [self.contentView addSubview: myDetailTextLabel]; 
    } 
    return self; 
} 

- (void) dealloc { 
    [myTextLabel release]; 
    [myDetailTextLabel release]; 
    [super dealloc]; 
} 

- (void) layoutSubviews { 

    // Let the super class UITableViewCell do whatever layout it wants. 
    // Just don't use the built-in textLabel or detailTextLabel properties 
    [super layoutSubviews]; 

    // Now do the layout of your custom views 

    // Let the labels size themselves to accommodate their text 
    [myTextLabel sizeToFit]; 
    [myDetailTextLabel sizeToFit]; 

    // Position the labels at the top of the table cell 
    CGRect newFrame = myTextLabel.frame; 
    newFrame.origin.x = CGRectGetMinX (self.contentView.bounds); 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [myTextLabel setFrame: newFrame]; 

    // Put the detail text label immediately to the right 
     // w/10 pixel gap between them 
    newFrame = myDetailTextLabel.frame; 
    newFrame.origin.x = CGRectGetMaxX (myTextLabel.frame) + 10.; 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [myDetailTextLabel setFrame: newFrame]; 
} 

@end 

在MyTableViewCell,你會忽略內置的文本標籤和使用自己定製的UILabels。您可以完全控制將它們放置在表視圖單元格的內容區域中。

我要離開很多東西了。在使用文本標籤進行自定義佈局時,您應該考慮:

  • 找出您自己的佈局算法。

    我正在使用上面的佈局算法來調整自定義UILabels以適應其文本內容,然後將它們並排放置。你可能會想要更適合你的應用的東西。

  • 保留內容視圖中的自定義標籤。

    在-layoutSubviews中,您可能希望邏輯保持自定義UILabels的大小和位置,使其不會超出內容矩形的範圍。使用我的樸素的佈局邏輯,任何長文本放入UILabel(或兩者)都可能導致標籤被定位在內容視圖邊界之外。

  • 如何處理-viewDidLoad/-viewDidUnload。

    如上所述,這個子類不處理從nib加載。您可能需要使用IB來佈局你的,如果你這樣做,你就需要考慮-viewDidLoad/-viewDidUnload/-initWithCoder:

+0

感謝layoutSubviews的超級透徹照明。不知道這是如此容易使用。涼。 – dugla 2010-08-01 20:21:38

+0

很好的答案,但我認爲你應該重寫initWithStyle:reuseIdentifier:而不是initWithFrame:方法。 – Rodrigo 2011-07-05 11:46:20

+1

我不確定重寫'initWithStyle:reuseIdentifier:'vs'initWithFrame'有很多好處。特別是因爲可以在初始化之後明確設置reuseIdentifier。對於UITableViewCell子類,也許一個-initWithReuseIdentifier:會是一個更方便的指定初始化程序。對於單元格子類,忽略'style'屬性/讓它採用默認值似乎是最佳做法。也就是說,你可以定義你自己的風格常量。但誰會使用它? – 2011-07-11 16:46:51

0

所述的UITableViewCell爲textLabel和detailTextLabel的佈局不直接修改的,除了通過拾取由所述API提供的定義的樣式之一。

typedef enum { 
    UITableViewCellStyleDefault, 
    UITableViewCellStyleValue1, 
    UITableViewCellStyleValue2, 
    UITableViewCellStyleSubtitle 
} UITableViewCellStyle; 

如果您想自定義的UITableViewCell佈局,你需要它的子類,並覆蓋-layoutSubviews方法。


- (void) layoutSubviews { 
    // [super layoutSubViews]; // don't invoke super 

    ... do your own layout logic here 
} 
+0

layoutSubviews是一種我從來沒有重寫過的方法,但記錄不完整。你能詳細說明一下嗎?謝謝。 – dugla 2010-07-31 11:04:54

2

在你的UITableViewCell子類下面的方法應該快速簡潔將textLabel和detailTextLabel對齊到單元格的頂部(點擊Bill的代碼),而不添加任何自定義視圖。

- (void) layoutSubviews 
{ 
    [super layoutSubviews]; 

    // Set top of textLabel to top of cell 
    CGRect newFrame = self.textLabel.frame; 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [self.textLabel setFrame:newFrame]; 

    // Set top of detailTextLabel to bottom of textLabel 
    newFrame = self.detailTextLabel.frame; 
    newFrame.origin.y = CGRectGetMaxY (self.textLabel.frame); 
    [self.detailTextLabel setFrame:newFrame]; 
} 
相關問題