По умолчанию экземпляр UITableViewCell располагает пару маркировки textLabel/detailTextLabel в центр ее родительского представления. Я предпочитаю выравнивать пару к вершине ячейки. Как я делаю это программно?
Спасибо,
Doug
В документах описывается - [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 вы можете попробовать несколько вариантов:
В , связанный с вопросом 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
В MyTableViewCell вы бы проигнорировали встроенные текстовые метки и использовали свои собственные пользовательские UILabels.Вы полностью контролируете их размещение в прямоугольнике содержимого ячейки табличного представления.
Я многое опускаю. Создавая собственный макет с текстовыми метками, вам нужно подумать:
Выяснить собственный алгоритм макета.
Я использую описанный выше алгоритм компоновки, который изменяет размер пользовательских меток UILabel в соответствии с их текстовым содержимым, а затем размещает их рядом. Скорее всего, вам понадобится что-то более конкретное для своего приложения.
Сохранение пользовательских меток в представлении содержимого.
В -layoutSubviews вы можете захотеть, чтобы логика сохраняла размер и расположение настраиваемых UILabels, чтобы они не выходили за пределы прямоугольника содержимого. С моей наивной логикой макета любой длинный текст, помещенный в UILabel (или в оба), может привести к тому, что метки будут расположены прямо за пределами границ представления содержимого.
Как обрабатывать -viewDidLoad / -viewDidUnload.
Как указано выше, этот подкласс не обрабатывает загрузку из пера. Возможно, вы захотите использовать IB для компоновки своей ячейки, и если вы это сделаете, вам нужно подумать о -viewDidLoad / -viewDidUnload / -initWithCoder:
Макеты textLabel и detailTextLabel UITableViewCell не поддаются прямой модификации, за исключением выбора одного из определенных стилей, предоставляемых API.
typedef enum {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
} UITableViewCellStyle;
Если вы хотите настроить макет UITableViewCell, вам необходимо создать его подкласс и переопределить метод -layoutSubviews
.
- (void) layoutSubviews {
// [super layoutSubViews]; // don't invoke super
... do your own layout logic here
}