UITableViewCell中。如何以编程方式将textLabel对齐到顶部?

时间:2010-07-28 11:42:24

标签: iphone objective-c uitableview

默认情况下,UITableViewCell实例将标签对textLabel / detailTextLabel定位在其父视图的中心。我更喜欢将这对对齐到单元格的顶部。我该如何以编程方式执行此操作?

谢谢,
道格

3 个答案:

答案 0 :(得分: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. 创建两个自己的UILabel以提供文本和详细文本
    2. 将它们添加到self.contentView和
    3. override -layoutSubviews用于操纵自定义UILabel视图的位置
  3. related SO question中,建议避免使用#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中,您将忽略内置文本标签并使用您自己的自定义UILabel。您可以完全控制在表格视图单元格的内容矩形中定位它们。

    我要留下很多东西。在使用文本标签进行自定义布局时,您需要考虑:

    • 找出自己的布局算法。

      我正在使用上面的布局算法调整自定义UILabels的大小以适应其文本内容,然后将它们并排放置。您可能想要更具体的应用程序。

    • 在内容视图中保留自定义标签。

      在-layoutSubviews中,您可能需要逻辑来保持自定义UILabel的大小和位置,以便它们不会超出内容rect的范围。使用我的天真布局逻辑,任何落入UILabel(或两者)的长文本都可能导致标签位于内容视图边界之外。

    • 如何处理-viewDidLoad / -viewDidUnload。

      如上所述,此子类不处理从nib加载的内容。您可能希望使用IB来布局您的单元格,如果这样做,您需要考虑-viewDidLoad / -viewDidUnload / -initWithCoder:

答案 1 :(得分: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];
}

答案 2 :(得分: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
}