Можно ли иметь разную высоту в ячейке UITableView, когда я использую несколько разных способов отображения ячейки?
Я потратил несколько дней, чтобы понять это, но, похоже, решения не существует. У меня есть очень простая ячейка UITableView с двумя метками. Одна из них будет одной строкой, вторая будет многострочной. Второй будет разной высоты. Вот пример того, что я пытаюсь создать ( UIStackViews внутри UITableViewCells):
Читая сотни сообщений SO, сотни блогов и просматривая сайты разработчиков Apple, можно найти неограниченное количество способов написать это. После экспериментов с сотнями разных способов, я все еще не могу отобразить текст таким образом. Я думаю, что некоторые проблемы связаны с тем фактом, что я использую 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
}
Который производит это:
11 ответов
Высота ячейки табличного представления определяется таблицей на основе rowHeight
свойство или возвращаемое значение optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
из таблицы просмотра делегата.
Высота, которая может быть установлена программистом для UITableViewCell через его свойство frame, игнорируется!
Следовательно, вам нужно вычислить желаемую высоту каждой ячейки программно. Тогда вам нужно реализовать optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
из табличного представления делегат для каждой из ячеек.
Если размер ячейки изменяется во время отображения табличного представления, вам необходимо:
- перезагрузить стол с
reloadData()
отUITableView
, или же - обновить ячейку с
func reloadRowsAtIndexPaths(_ indexPaths: [NSIndexPath], withRowAnimation animation: UITableViewRowAnimation)
отUITableView
,
редактировать
На самом деле, поскольку вы используете ограничения в своем представлении, оно должно работать без использования ``.
Попробуйте заменить код в 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.
Пожалуйста, дайте мне знать, как это происходит!
Я предлагаю вам не использовать стека для этого. Просто возьмите пользовательскую ячейку с меткой в соответствии с вашими требованиями, и ячейка изменится автоматически в соответствии с размером текста метки.
Проверьте, здесь я приложил демо.
UITableview ячейка Авторазмер в соответствии с текстовым размером
Выход:-
В 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
Прежде всего, если вам не нужен UIStackView
для какой-либо другой цели, которую вы не упоминаете в своем вопросе, не используйте их. Многострочные метки и ячейки динамической высоты хорошо работают без них (без необходимости не усложняйте код, если они не нужны).
В iOS нет ошибок, которые мешают этому работать, о чем я знаю. Ячейки динамического размера прекрасно работают с Auto Layout, все, что вам нужно сделать, это установить правильные ограничения в ячейках и установить rowHeight
а также estimatedRowHeight
свойства табличного представления.
Наиболее вероятная причина того, что это не работает для вас, заключается в том, что вы не наложили все необходимые ограничения в своей камере. Необходимые ограничения:
- Верхнее ограничение от содержимого ячейки (т. Е. Многострочного ярлыка) до верхней части представления содержимого ячейки.
- Ведущее ограничение от вашей однострочной метки слева от ячейки
- Конечное ограничение от вашей многострочной метки справа от вашей ячейки
- Нижнее ограничение от нижней части многострочного ярлыка до нижней части ячейки
Я думаю, что вы упускаете пункт 4.
редактировать
Согласно вашим комментариям, вы используете UIStackView
чтобы выровнять верхние базовые линии между однострочными и многострочными метками. Под этим я понимаю, что вы хотите, чтобы ваши метки выровнялись так:
Чтобы получить такое поведение, вам не нужноUIStackView
, Просто задайте ограничения для меток, чтобы многострочная метка определяла высоту ячейки. На следующем рисунке показаны верхние базовые линии, выровненные между двумя метками (т.е. первые строки каждой метки выровнены).
Обратите внимание, что для левой метки требуется только ограничение сверху и снизу, тогда как для правой метки нужны верхняя, нижняя и нижняя границы, поскольку она определяет высоту ячейки.
Таким образом, для динамических ячеек табличного представления требуются три вещи:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 100
- Содержимое ячейки должно иметь все четыре ограничения (ведущий, конечный, верхний и нижний) для определения высоты ячейки.
Для этого вам нужно использовать ячейку табличного представления Self sizing, т.е. само табличное представление вычисляет высоту, необходимую для каждой ячейки, чтобы отобразить ее содержимое, это может быть достигнуто в двух строках кода:
Шаг 1: установить оценочную высоту для табличного представления tableView.estimatedRowHeight = 33.0 step2: установить высоту строки tableView в UITableViewAutomaticDimension tableView.rowHeight = UITableViewAutomaticDimension
Вот учебник для подробного описания http://www.appcoda.com/self-sizing-cells/
Как уже упоминали другие, убедитесь, что вы позволяете динамически изменять размеры ячеек табличного представления:
tableView.estimatedRowHeight = <estimatedHeightValue>
tableView.rowHeight = UITableViewAutomaticDimension
Но вы упомянули, что вы уже делаете это.
Остальная часть проблемы - это случай отсутствия ограничений. Вы уже сказали autolayout, что хотите, чтобы ваша многострочная метка соответствовала верху и низу стекового представления, как показано в коде ниже:
englishWordLabel.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
englishWordLabel.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true
Но вы не упомянули, что это представление стека связано с представлением содержимого ячейки (ее суперпредставлением). Это необходимо для динамически изменяемых размеров ячеек, потому что согласно Apple:
Чтобы определить высоту ячейки, вам нужна непрерывная цепочка ограничений и представлений (с определенной высотой), чтобы заполнить область между верхним краем представления содержимого и его нижним краем. Если ваши представления имеют внутреннюю высоту содержимого, система использует эти значения. Если нет, вы должны добавить соответствующие ограничения по высоте либо к представлениям, либо к представлению содержимого.
Ваши ярлыки имеют встроенный контент, так что это не проблема, но чтобы завершить "непрерывную цепочку", вы должны указать autolayout, что верх и низ представления стека должны быть равны верху и низу представления контента, например:
// stackView.superview! is the table view cell's content view
stackView.topAnchor.constraintEqualToAnchor(stackView.superview!.topAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(stackView.superview!.bottomAnchor).active = true
Добавьте эти две строки после того, как вы добавили представление стека к представлению контента, и я верю, что вы будете в бизнесе.
К вашему сведению, даже если вы программно добавляете эти представления к своим ячейкам, как вы, вы все равно можете визуально отлаживать проблемы с компоновкой с помощью потрясающей возможности Xcode Capture View Hierarchy. Пока ваше приложение выполняется из Xcode, щелкните пункт меню Debug> View Debugging> Capture View Hierarchy. Очень легко увидеть, что происходит в иерархии ваших представлений, какие ограничения активны, куда исчезли ваши исчезающие представления и т. Д.
2-й FYI, уничтожение представлений, а затем повторное создание новых каждый раз, когда ячейка появляется на экране, значительно снижает производительность при прокрутке. Как можно больше вы захотите взять существующие представления из ячеек с изъяном и переназначить их содержимое с соответствующим содержимым для этой строки (и, таким образом, избежать создания экземпляров представления). Вы все еще можете сделать это, используя свой чисто программный способ, выполнив процедуру удаления очереди из ячейки и вызова cell.viewWithTag
для каждого возможного просмотра. Если метод возвращает nil
Вы делаете единовременную реализацию представления для ячейки и присваиваете представление тег (скажем, 1 для wordLabel
и 2 для englishWordLabel
). Затем назначьте правильное содержимое строки для представления.
У меня были очень похожие проблемы с autoLayout снова и снова. Я редко использую stackViews, я обычно использую их, когда у меня есть требование добавить / удалить или показать / скрыть представление. Когда я этого не делаю, я выбираю только ограничения. Я чувствую, что просмотры стека довольно глючные в довольно многих случаях. Особенно в Xib's. Я не знаю, почему это имеет значение, но, кажется, всегда вызывает предупреждения, которые я не могу удалить, при использовании более 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
}
}
Я объединил это с протоколом, который заставляет все ячейки брать словарь для установки своих данных. Затем я могу обернуть этот метод, чтобы взять и передать в словарь и многократно использовать код снова и снова.
Это работает без проблем для меня в течение очень долгого времени.
Это очень просто. Давайте идти шаг за шагом.
1 установить приблизительный вес таблицы. Это позволяет легко и быстро загрузить ячейку.
2. Установите для свойства rowHeight свойства table view значение UITableViewAutomaticDimension.and не используйте heightForRowAtIndexPath.
3.Введите все верхнее нижнее начальное и конечное ограничения на оба значения Label.its.
Позволяет рок-н-ролл не нужно использовать stackView
То, чего вы хотите добиться, может быть сделано простой реализацией heightForRowAtIndexPath из делегата tableView.
Если вы не уверены, какая ячейка должна иметь какую высоту, вы можете просто рассчитать ее во время выполнения.
Подход, которым я буду следовать:
Я создам UIView SubClass
как container view
который будет содержать "метку слова" и "английскую метку слова". это намного проще, отдельный код и обслуживаемый.
Я создам подкласс ячейки и буду использовать этот вид контейнера как subView of cell'scontent view
,
Затем я буду использовать весь этот набор в cellForRowAtIndex
,
Я также сделаю некоторую реализацию кода в heightForRow
, Чтобы сделать динамическую высоту строки ячейки во время выполнения, вы должны реализовать этот метод. 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's 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];
}
пара вещей, которые я не должен использовать в вышеупомянутом подходе:
1. Не использовать свойство автоматического расчета высоты строки. 2.Не использовать расчетную высоту 3.Не нужно ненужных обновлений ограничений. 4.Не использовать автоматическую максимальную ширину макета. 5. Не использовать systemLayoutSizeFittingSize (должен был использовать, но у меня не работает, я не знаю, что он делает внутри), но вместо этого мой метод -(float)getViewHeight работает, и я знаю, что он делает внутри.
Я поделился с вами наиболее релевантными блоками кода, но до сих пор не работал над Swift. Но основы остаются такими же. Спасибо
Начиная с iOS 9.1 UIStackView
не реализует intrinsicContentSize:
поэтому табличное представление не может рассчитать высоту каждой ячейки, поэтому вместо этого они отображаются на предполагаемой высоте.
Таким образом, в идеале вы должны упростить свой код, чтобы означать, что вы не используете представление стека и не продолжаете добавлять и удалять (и создавать и уничтожать) представления все время. Корень решения заключается в том, чтобы не использовать представление стека, хотя.
Вы можете продолжать использовать представление стека, если хотите, но вам нужно будет создать подкласс и реализовать intrinsicContentSize:
, Ваша причина использования стекового представления не должна быть обязательной, поскольку вы можете настроить ограничения так, чтобы они соответствовали первым базовым показателям.
- (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 *cellIdentifier=@"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;
}