Возможно ли иметь разную высоту в ячейке UITableView, когда я использую несколько разных способов отображения ячейки?
Я потратил несколько дней, пытаясь понять это, но, похоже, не существует решения. У меня очень простая ячейка UITableView с двумя ярлыками. Одна из них будет одной строкой, вторая будет многострочной. Второй будет отличаться по высоте. Вот пример того, что я пытаюсь произвести (UIStackViews внутри UITableViewCells):
Отчитав сотни сообщений SO, сотни блогов, чистящих сайты Apple Developer, кажется, существует неограниченное количество способов написать это. После того, как я экспериментировал с сотнями разных способов, я до сих пор не могу отобразить текст так. Я думаю, что некоторые проблемы связаны с тем, что я использую 3 различные изменения ячейки UITableView в одном UITableView.
Вот мой код из моей последней попытки cellForRowAtIndexPath
:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell!
let (parent, isParentCell) = self.findParent(indexPath.row)
if !isParentCell {
let categories = ["words", "translation","commentary"]
if categories[parent] == "words" {
cell = tableView.dequeueReusableCellWithIdentifier(childWordsCellIdentifier, forIndexPath: indexPath) as UITableViewCell
// Reset content
for subview in cell.contentView.subviews {
subview.removeFromSuperview()
}
cell.prepareForReuse()
let words = self.page.valueForKey("words")!.allObjects as! [Word]
let wordsInOrder = words.sort({Int($0.order!) < Int($1.order!) })
let word = wordsInOrder[indexPath.row - 1]
let labelWidth = (self.view.frame.width - 80) / 2
let wordLabel = UILabel(frame: CGRectZero)
wordLabel.text = word.valueForKey("sanskrit") as? String
wordLabel.font = UIFont(name: "EuphemiaUCAS-Bold", size: 16)
wordLabel.numberOfLines = 0
wordLabel.translatesAutoresizingMaskIntoConstraints = false
wordLabel.layer.borderColor = UIColor.greenColor().CGColor
wordLabel.layer.borderWidth = 1.0
let widthWordConstraint = wordLabel.widthAnchor.constraintEqualToConstant(labelWidth)
widthWordConstraint.priority = 300
widthWordConstraint.active = true
let englishWordLabel = UILabel(frame: CGRectZero)
englishWordLabel.text = "Foobar don't want to play my game with my anymore."
englishWordLabel.font = UIFont(name: "STHeitiTC-Light", size: 16)
englishWordLabel.numberOfLines = 0
englishWordLabel.preferredMaxLayoutWidth = labelWidth
englishWordLabel.translatesAutoresizingMaskIntoConstraints = false
let englishWordConstraint = englishWordLabel.widthAnchor.constraintEqualToConstant(labelWidth)
englishWordConstraint.priority = 300
englishWordConstraint.active = true
englishWordLabel.layer.borderColor = UIColor.blueColor().CGColor
englishWordLabel.layer.borderWidth = 1.0
let stackView = UIStackView()
stackView.axis = .Horizontal
stackView.distribution = .FillProportionally
stackView.alignment = .FirstBaseline
stackView.spacing = 15
stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
stackView.layoutMarginsRelativeArrangement = true
stackView.addArrangedSubview(wordLabel)
stackView.addArrangedSubview(englishWordLabel)
stackView.translatesAutoresizingMaskIntoConstraints = false
englishWordLabel.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
englishWordLabel.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true
cell.contentView.addSubview(stackView)
cell.contentView.layoutIfNeeded()
} else {
cell = tableView.dequeueReusableCellWithIdentifier(childCellIdentifier, forIndexPath: indexPath) as UITableViewCell
// Reset content
cell.textLabel!.text = ""
for subview in cell.contentView.subviews {
subview.removeFromSuperview()
}
cell.prepareForReuse()
cell.textLabel!.text = self.page.valueForKey(categories[parent]) as? String
cell.textLabel!.textColor = UIColor(red: 35/255.0, green: 31/255.0, blue: 32/255.0, alpha: 1.0)
cell.textLabel!.font = UIFont(name: "STHeitiTC-Light", size: 16)
}
}
else {
// Parent
cell = tableView.dequeueReusableCellWithIdentifier(parentCellIdentifier, forIndexPath: indexPath)
cell.textLabel!.text = self.dataSource[parent].title
cell.textLabel!.textColor = UIColor(red: 66/255.0, green: 116/255.0, blue: 185/255.0, alpha: 1.0)
cell.textLabel!.font = UIFont(name: "STHeitiTC-Light", size: 20)
}
cell.selectionStyle = .None
cell.textLabel!.translatesAutoresizingMaskIntoConstraints = false
cell.textLabel!.numberOfLines = 0
cell.textLabel!.lineBreakMode = .ByWordWrapping
return cell
}
Что производит это:
Ответы
Ответ 1
Высота ячейки представления таблицы определяется таблицей на основе свойства rowHeight
или возвращаемого значения optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
из делегата представления таблицы.
Высота, которая может быть задана программистом для UITableViewCell через его свойство кадра, игнорируется!
Следовательно, вам необходимо определить желаемую высоту каждой ячейки программно. Затем вам нужно реализовать optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
из делегата представления таблицы для каждой из ячеек.
Если размер ячейки изменяется при отображении представления таблицы, вам необходимо либо:
- перезагрузите таблицу с помощью
reloadData()
из UITableView
или
- обновите ячейку с помощью
func reloadRowsAtIndexPaths(_ indexPaths: [NSIndexPath], withRowAnimation animation: UITableViewRowAnimation)
от UITableView
.
Edit
Фактически, поскольку вы используете ограничения в своем представлении, он должен работать без использования ``.
Попробуйте заменить код if categories[parent] == "words" { .. }
на:
cell = tableView.dequeueReusableCellWithIdentifier(childWordsCellIdentifier, forIndexPath: indexPath) as UITableViewCell
// Reset content
for subview in cell.contentView.subviews {
subview.removeFromSuperview()
}
cell.prepareForReuse()
let words = self.page.valueForKey("words")!.allObjects as! [Word]
let wordsInOrder = words.sort({Int($0.order!) < Int($1.order!) })
let word = wordsInOrder[indexPath.row - 1]
let wordLabel = UILabel(frame: CGRectZero)
wordLabel.text = word.valueForKey("sanskrit") as? String
wordLabel.font = UIFont(name: "EuphemiaUCAS-Bold", size: 16)
wordLabel.numberOfLines = 0
wordLabel.translatesAutoresizingMaskIntoConstraints = false
wordLabel.layer.borderColor = UIColor.greenColor().CGColor
wordLabel.layer.borderWidth = 1.0
let englishWordLabel = UILabel(frame: CGRectZero)
englishWordLabel.text = "Foobar don't want to play my game with my anymore."
englishWordLabel.font = UIFont(name: "STHeitiTC-Light", size: 16)
englishWordLabel.numberOfLines = 0
let stackView = UIStackView()
stackView.axis = .Horizontal
stackView.distribution = .FillProportionally
stackView.alignment = .Fill // EDIT
stackView.spacing = 15
stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
stackView.layoutMarginsRelativeArrangement = true
stackView.addArrangedSubview(wordLabel)
stackView.addArrangedSubview(englishWordLabel)
stackView.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(stackView)
cell.contentView.leadingAnchor.constraintEqualToAnchor(stackView.leadingAnchor).active = true
cell.contentView.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
cell.contentView.trailingAnchor.constraintEqualToAnchor(stackView.trailingAnchor).active = true
cell.contentView.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true
cell.contentView.layoutIfNeeded()
Также я бы использовал для разных классов ячеек для этой задачи, а не для удаления представлений в ContentView.
Пожалуйста, дайте мне знать, как это происходит!
Ответ 2
Я предлагаю вам не использовать представление стека для этого. Просто возьмите пользовательскую ячейку с ярлыком в соответствии с вашим требованием, и ячейка автоматически изменит размер в соответствии с размером текста метки.
Проверьте, здесь я приложил демо.
UITableview cell Autoresize В соответствии с текстом
Выход: -
В viewdidload
super.viewDidLoad()
self.tblView.estimatedRowHeight = 100;
self.tblView.rowHeight = UITableViewAutomaticDimension;
self.tblView.setNeedsLayout()
self.tblView.layoutIfNeeded()
Не забудьте установить свойство Numberoflines=0
свойства UILabel.
Изменить: - Если вам требуется пошаговое руководство относительно того, как установить ограничение на UILabel,
проверьте эту ссылку,
Отрегулируйте высоту UILabel в зависимости от текста
Изменить: - Здесь у меня есть 2 ярлыка в ячейке в соответствии с вашим изображением выше. Просто установите ограничение таким образом.
Метка 1: - Верх, Ведущий, (Высота и ширина согласно вашему требованию)
Ярлык 2: - Верх, нижний, ведущий от метки 1, переход от Superview
Ответ 3
То, что вы хотите достичь, может быть выполнено простой реализацией heightForRowAtIndexPath из делегата tableView.
Если вы не знаете, какая ячейка должна иметь высоту, вы можете просто вычислить ее во время выполнения.
Ответ 4
Для этого вам нужно использовать ячейку просмотра таблицы размеров, т.е. сам вид таблицы вычисляет высоту, необходимую для каждой ячейки, чтобы отображать ее содержимое, которое может быть достигнуто в двух строках кода:
Шаг1: установите высоту оценки для представления таблицы
tableView.estimatedRowHeight = 33.0
step2: установить tableView высоту строки в UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
Вот учебник для подробного описания http://www.appcoda.com/self-sizing-cells/
Ответ 5
Подход я будет следующим:
Я создам UIView SubClass
как container view
, который будет содержать "метку слова" и "английскую метку слова". это намного проще, отдельный код и maintanable.
Я создам подкласс ячейки и использую этот вид контейнера как subView of cell'scontent view
.
Затем я использую всю эту настройку в cellForRowAtIndex
.
Я также сделаю некоторую реализацию кода в heightForRow
. Что касается динамической высоты строки ячейки во время выполнения, то u должен реализовать этот метод heightForRow
.
Результат вывода будет примерно таким, как показано ниже, он имеет один UIImageView и два UILabel и пользовательский серосепаратор. Эта динамическая высота ячейки основана на том, что когда-либо высота изображения и какая длина строки должна отображаться в UILabel:
Я поделюсь некоторым фрагментом кода для вас. Итак, здесь приведен пример концептуального кода для представления контейнера:
Наиболее важная установка ограничений для представления в контейнере (например, VenueViewContainer: UIView) выглядит следующим образом (для вашего случая вы можете создавать метки по горизонтали, а не по вертикали):
"V:|-0-[venueImage]-10-[venueName]-2-[sportName]-10-[lblSeperator(10)]",
"H:|-0-[venueImage]-0-|",
"H:|-20-[venueName]-20-|",
"H:|-20-[sportName]-20-|",
"H:|-0-[lblSeperator]-0-|",
Обязательно установите эти два свойства для своих меток:
[lbl setNumberOfLines:0];
[lbl setLineBreakMode:NSLineBreakByWordWrapping];
В вашем файле реализации VenueViewContainer создайте метод:
/*!This method is responsible for getting view dynamic height .*/
-(float)getViewHeight
{
[self layoutIfNeeded];
CGFloat maxY = 0;
for (UIView *subview in self.subviews) {
maxY = MAX(CGRectGetMaxY(subview.frame),maxY);
}
return maxY;
}
/*!
This method is responsible for set up Venue.
@param venue object
*/
#pragma -mark data population
- (void)setupViewWithVenue:(Venue *)venue
{
self.venueLabel.text = @"my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue last";
self.sportName.text = @"my sport my sport my sport my sport my sport my sport my sport my sport my sport my sport my sport my sport my sport my sport last";
[self.venueImage setImageWithURLString:venue.venueImageUrl defaultImage:[UIImage imageNamed:@"venueinfo_main"]];
}
Теперь поговорим о пользовательской ячейке. подкласс UITableViewCell. Реализация такая тонкая:
@implementation VenueCellTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self setUpContainer];
[self setUpConstraints];
}
return self;
}
/*!
This method is responsible for set up Container
*/
-(void)setUpContainer{
aViewContainer = [[VenueViewContainer alloc] initWithFrame:CGRectZero];
[aViewContainer setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.contentView addSubview:aViewContainer];
}
/*!constraints setup*/
-(void)setUpConstraints{
/*!
dictionary of views for autolayout
*/
NSMutableDictionary* views;
views = [NSMutableDictionary new];
UIView *parentView = self.contentView;
views[@"aViewContainer"] = aViewContainer;
views[@"parentView"] = parentView;
NSArray* constraints;
NSString* format;
/*!
layouting horizontal
*/
format = @"|-0-[aViewContainer]-0-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[parentView addConstraints:constraints];
/*!
layouting vertical
*/
format = @"V:|-0-[aViewContainer]-0-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[parentView addConstraints:constraints];
}
/*!
This method is responsible for set up venue
@param venue object
*/
- (void)setupCellWithVenue:(Venue *)venue
{
[aViewContainer setupViewWithVenue:venue];
}
/*!
This method is responsible to get cell height dynamically
@param venue object
*/
-(float)getCellHeight
{
return [aViewContainer getViewHeight];
}
Это связано с настройкой вашей ячейки.
теперь говорят о cellForRow
и heightForRow
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VenueCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVenueCellIdentifier];
if (nil == cell) {
cell = [[VenueCellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:kVenueCellIdentifier];
}
[cell setBackgroundColor:[[AWPViewFactory sharedInstance]getColor:@"colorWhite"]];
#pragma uncomment below line as per ur need
// Venue *venue = [_dataSourceArray objectAtIndex:indexPath.row];
[cell setupCellWithVenue:nil];
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
return cell;
}
#pragma mark - UITableViewDelegate methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Use the dictionary of offscreen cells to get a cell for the reuse identifier, creating a cell and storing
// it in the dictionary if one hasn't already been added for the reuse identifier.
// WARNING: Don't call the table view dequeueReusableCellWithIdentifier: method here because this will result
// in a memory leak as the cell is created but never returned from the tableView:cellForRowAtIndexPath: method!
VenueCellTableViewCell *cell = [self.offscreenCells objectForKey:kVenueCellIdentifier];
if (!cell) {
cell = [[VenueCellTableViewCell alloc] init];
[self.offscreenCells setObject:cell forKey:kVenueCellIdentifier];
}
// Configure the cell for this indexPath
#pragma uncomment below line as per ur need
// Venue *venue = [_dataSourceArray objectAtIndex:indexPath.row];
[cell setupCellWithVenue:nil];
return [cell getCellHeight];
}
пару вещей, которые я не должен использовать в следующем aproach:
1. Нет использования автоматического вычисления высоты строки.
2.Нет использования расчетной высоты
3. Нет необходимости в ненужных updateConstraints.
4.Не используйте автоматическую максимальную ширину макета макета.
5. Нет использования systemLayoutSizeFittingSize (должен использовать, но не работать для меня, я не знаю, что он делает изнутри), но вместо этого мой метод - (float) getViewHeight работает, и я знаю, что он делает внутри.
Я поделился с вами самыми важными блоками кода, я еще не работал над быстрым. Но основы остаются такими же.
Благодаря
Ответ 6
Прежде всего, если вам не нужен UIStackView
для какой-либо другой цели, о которой вы не упоминаете в своем вопросе, не используйте их. Многострочные метки и ячейки динамической высоты хорошо работают без них (не обязательно усложнять код, если они не нужны).
В iOS нет ошибок, которые перестают работать, что я знаю. Ячейки с динамическим размером отлично работают с Auto Layout, все, что вам нужно сделать, это установить правильные ограничения в ячейках и установить свойства rowHeight
и estimatedRowHeight
в представлении таблицы.
Наиболее вероятная причина, по которой это не работает для вас, заключается в том, что вы не поставили все необходимые ограничения в своей ячейке. Необходимые ограничения:
- Верхнее ограничение содержимого вашей ячейки (т.е. многострочная метка) в верхней части представления содержимого ячейки
- Ведущее ограничение от вашей однострочной метки слева от ячейки
- Следящее ограничение на вашей многострочной метке справа от вашей ячейки
- Нижнее ограничение от нижней части вашей многострочной метки до нижней части вашей ячейки
Я думаю, что вам не хватает точки 4.
Edit
Согласно вашим комментариям, вы используете UIStackView
, чтобы выровнять верхние базовые линии между одиночными и многострочными метками. Таким образом, я понимаю, что вы хотите, чтобы ваши метки выравнивались так:
Чтобы получить это поведение, вам не нужен UIStackView
. Просто дайте ограничениям меток, чтобы позволить многострочной метке определять высоту ячейки. На следующем изображении показаны верхние базовые линии, выровненные между двумя метками (т.е. Первые строки каждой метки выровнены).
Обратите внимание, что левому ярлыку требуется только главное и верхнее ограничение, тогда как правой метке нужен верхний, конечный и нижний, поскольку он определяет высоту ячейки.
Таким образом, для динамических ячеек таблицы требуется три вещи:
-
tableView.rowHeight = UITableViewAutomaticDimension
-
tableView.estimatedRowHeight = 100
- Содержимое ячейки должно содержать все четыре ограничения (ведущие, конечные, верхние и нижние) для определения высоты ячейки.
Ответ 7
Это очень просто. Команды идут шаг за шагом.
1. установите значение оценочного графика таблицы. Это упрощает и ускоряет загрузку ячейки.
2. Установите свойство rowHeight таблицы view как UITableViewAutomaticDimension.и не используйте heightForRowAtIndexPath.
3.Введите все верхние и нижние ограничения для обоих ярлыков Label.its.
Позволяет рок-н-ролл
нет необходимости использовать stackView
Ответ 8
В iOS 9.1 UIStackView
не реализуется intrinsicContentSize:
, поэтому представление таблицы не может вычислить высоту каждой ячейки, поэтому вместо этого они отображаются на предполагаемой высоте.
Итак, в идеале вы упростили бы ваш код, чтобы вы не использовали представление стека, и вы не продолжаете добавлять и удалять (и создавать и уничтожать) представления все время. Корень решения состоит в том, чтобы не использовать представление стека, хотя.
Вы можете продолжить использовать представление стека, если хотите, но вам нужно создать подкласс и реализовать intrinsicContentSize:
. Ваша причина использовать представление стека не требуется, хотя вы можете настроить ограничения для соответствия первым базовым линиям.
Ответ 9
Как уже упоминалось, убедитесь, что вы разрешаете ячейкам просмотра таблицы динамически изменять размер с помощью:
tableView.estimatedRowHeight = <estimatedHeightValue>
tableView.rowHeight = UITableViewAutomaticDimension
Но вы уже упоминали, что уже делаете это.
Остальная часть проблемы - это случай недостающих ограничений. Вы уже сказали автоопределению, что хотите, чтобы ваш многострочный ярлык соответствовал верхней и нижней части представления стека, как в следующем коде:
englishWordLabel.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
englishWordLabel.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true
Но вы не упомянули для автоопределения, как это представление стека связано с представлением содержимого ячейки (его супервизор). Это необходимо для динамически размерных ячеек, поскольку согласно Apple:
Чтобы определить высоту ячеек, вам нужна непрерывная цепочка ограничений и представлений (с определенными высотами), чтобы заполнить область между верхним краем представления контента и его нижним краем. Если ваши представления имеют высоту собственного контента, система использует эти значения. Если нет, вы должны добавить соответствующие ограничения по высоте, либо к представлениям, либо к самому представлению содержимого.
В ваших ярлыках есть встроенный контент, поэтому нет проблем, но для того, чтобы завершить "неразрывную цепочку", вам нужно сообщить автоопределению, что представление стека сверху и снизу должно быть равно представлению содержимого сверху и снизу, например
// stackView.superview! is the table view cell content view
stackView.topAnchor.constraintEqualToAnchor(stackView.superview!.topAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(stackView.superview!.bottomAnchor).active = true
Добавьте эти две строки после того, как вы добавили представление стека в представление контента, и я считаю, что вы будете в бизнесе.
FYI, даже если вы программно добавляете эти представления в свои ячейки, как и вы, вы все же можете визуально отлаживать проблемы с макетами довольно хорошо с помощью Xcode awesome Capture View Hierarchy. Пока ваше приложение запускается из Xcode, щелкните пункт меню Debug > View Debugging > Capture View Hierarchy. Очень легко понять, что происходит в вашей иерархии взглядов, какие ограничения активны, где исчезли ваши просмотры и т.д.
2-й FYI, уничтожая представления и затем восстанавливая новые, каждый раз, когда ячейка появляется на экране, значительно ухудшается производительность при прокрутке. Насколько это возможно, вы захотите использовать существующие представления из выделенных ячеек и переназначить их содержимое соответствующим содержимым для этой строки (и, таким образом, избежать создания экземпляра). Вы все еще можете сделать это, используя свой чисто программный способ делать вещи, выгружая ячейку и вызывая cell.viewWithTag
для каждого возможного вида. Если метод возвращает nil
, вы выполняете одноразовое создание представления для ячейки и даете тегу вида (скажем, 1 для wordLabel
и 2 для englishWordLabel
). Затем назначьте правильное содержимое строки для представления.
Ответ 10
У меня были очень похожие проблемы с autoLayout снова и снова. Я не использую stackViews много, я обычно использую их, когда у меня есть требование добавить/удалить или показать/скрыть представление. Когда я не делаю этого, я предпочитаю использовать ограничения. Я чувствую, что стоп-шоу довольно затруднительно в довольно многих обстоятельствах. Особенно в xib. Я не знаю, почему это имеет значение, но, похоже, всегда вызывает предупреждения, которые я не могу удалить при использовании более 1 метки.
Это говорит о том, что autoLayout тоже не без проблем, и все они в основном сосредоточены вокруг preferredMaxLayoutWidth
.
Чтобы объяснить, для того, чтобы AutouLayout вычислил высоту метки, ему нужно знать, какой шириной может быть метка. Когда у вас есть несколько ярлыков вместе, особенно в tableViewCell, это вызывает всевозможные проблемы.
Я спросил и впоследствии ответил на соответствующий вопрос здесь несколько дней спустя.
Что я сделал, добавлен подкласс UILabel, который всегда гарантирует, что preferredMaxLayoutWidth
обновляется всякий раз, когда метка изменена. Я недавно обновил его для iOS 8, iOS 9 и отдельную проблему, которую я нашел с модальными представлениями.
Итак, полные шаги:
- Создайте подкласс UIlabel.
- Создайте ячейку с вашими ярлыками, расположенными без UIStackViews.
- Задайте количество строк в 0 для одной или обеих меток в зависимости от вашей учетной записи.
- Установите ярлыки типа вашего подкласса.
- Внедрите метод
estimatedHeightForRowAtIndexPath
, чтобы угадать, какова высота.
- Вычислить высоту ячейки внутри
heightForRowAtIndexPath
.
Чтобы вычислить высоту, вы можете использовать что-то вроде этого (которое я отвлек на вспомогательный метод, который я могу использовать повторно)
// Set the cell data first, i.e. the label text, any programmatic fonts, font sizes etc.
if let tempCell = cell as? UITableViewCell
{
tempCell.width = tableView.width
let size = tempCell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
if tableView.separatorStyle != UITableViewCellSeparatorStyle.None
{
// +0.5 for seperator
return size.height+0.5
}
else
{
return size.height
}
}
Я объединил это с протоколом, который заставляет все ячейки использовать словарь для установки своих данных. Затем я могу завершить этот метод, чтобы взять и передать в словаре и повторно использовать код снова и снова.
Это работает без проблем для меня в течение очень долгого времени.
Ответ 11
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *firstLable = firstLable.text;
NSString *secondLable = SecondLable.text;
CGSize constraint = CGSizeMake(cell.frame.size.width/2, 20000.0f);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
CGRect firstLableRect = [firstLable boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f],
NSParagraphStyleAttributeName: paragraphStyle.copy} context:nil];
CGRect secondLableRect = [secondLable boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f], NSParagraphStyleAttributeName: paragraphStyle.copy}context:nil];
float max = MAX(firstLableRect.size.height, secondLableRect.size.height) + 20;
//20 for spacing 10 pc above and 10 pc below
return max ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *[email protected]"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.selectionStyle =UITableViewCellSelectionStyleNone;
NSString *lable1 = @"first label text";
NSString *lable2 = @"second lable text";
CGSize constraint = CGSizeMake(cell.frame.size.width/2-10, 20000.0f);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
CGRect firstLableRect = [lable1 boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f],
NSParagraphStyleAttributeName: paragraphStyle.copy} context:nil];
CGRect secondLableRect = [lable2 boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f], NSParagraphStyleAttributeName: paragraphStyle.copy}context:nil];
UILabel *firstLable = [[UILabel alloc]initWithFrame:CGRectMake(5,10,constraint.width,firstLableRect.size.height)];
[firstLable setLineBreakMode:NSLineBreakByWordWrapping];
firstLable.minimumScaleFactor = 15.0f;
[firstLable setNumberOfLines:0];
firstLable.textAlignment = NSTextAlignmentLeft;
[firstLable setFont:[UIFont fontWithName:@"your App font" size:16.0f]];
[cell.contentView addSubview:firstLable];
UILabel *secondLable = [[UILabel alloc]initWithFrame:CGRectMake(cell.frame.size.width/ 2+5,10,constraint.width,secondLableRect.size.height)];
[secondLable setLineBreakMode:NSLineBreakByWordWrapping];
secondLable.minimumScaleFactor = 15.0f;
[secondLable setNumberOfLines:0];
secondLable.textAlignment = NSTextAlignmentLeft;
[secondLable setFont:[UIFont fontWithName:@"your App font" size:16.0f]];
[cell.contentView addSubview:secondLable];
return cell;
}