默认情况下,UITableViewCell实例将标签对textLabel / detailTextLabel定位在其父视图的中心。我更喜欢将这对对齐到单元格的顶部。我该如何以编程方式执行此操作?
谢谢,
道格
答案 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的子类时,您可以尝试以下几种方法:
在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
}