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

dug*_*gla 9 iphone objective-c uitableview

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

谢谢,
道格

Bil*_*son 24

文档描述 - [UIView layoutSubviews]为

"Overridden by subclasses to layout subviews when layoutIfNeeded is invoked. The default implementation of this method does nothing."
Run Code Online (Sandbox Code Playgroud)

该描述不详细,但准确.在这种情况下,方法的行为是布局子视图.它将在设备方向更改时随时调用.每当调用-setNeedsLayout时,它也会安排在以后调用.

因为,UIView的实现没有做任何事情,(并且我对UIControl的设想相同),您可以获得完全的创作自由,使您的UIView子类子视图可以放置在您想要的任何位置.

在继承UITableViewCell的子类中,您可以尝试以下几个选项:

  1. 覆盖-layoutSubviews和
    1. 操纵内置textLabel和-detailLabel视图的位置.
  2. 覆盖-viewDidLoad,
    1. 创建两个自己的UILabel来提供文本和详细文本,
    2. 将它们添加到self.contentView,和
    3. override -layoutSubviews用于操纵自定义UILabel视图的位置

在一个相关的SO问题中,建议避免#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
Run Code Online (Sandbox Code Playgroud)

在MyTableViewCell中,您将忽略内置文本标签并使用您自己的自定义UILabel.您可以完全控制在表视图单元格的内容矩形中定位它们.

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

  • 找出你自己的布局算法.

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

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

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

  • 如何处理-viewDidLoad/-viewDidUnload.

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