故事板中的自定义单元行高度设置没有响应

我正在尝试调整我的表格视图中的一个单元格的单元格高度。 我从正在讨论的单元格的“大小检查器”中的“行高”设置resize。 当我在iPhone上运行应用程序时,单元格具有表格视图中“行大小”设置的默认大小。

如果我改变表格视图的“行大小”,那么所有单元格的大小都会改变。 我不想这样做,因为我只想要一个单元格的自定义大小。 我已经看到了很多有解决问题的scheme,但是如果可能的话,我宁愿通过故事板来完成。

dynamic单元rowHeight上,在UITableView上设置的rowHeight总是覆盖单个单元格的rowHeight。

但在静态单元rowHeight上,单个单元rowHeight设置的rowHeight可以覆盖UITableView的。

不知道这是一个错误,苹果可能会故意这样做?

如果你使用UITableViewController,实现这个方法:

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; 

在一行的function中,你可以select高度。 例如,

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) { return 100; } else { return 60; } } 

在这个例子中,第一行的高度是100像素,其他的是60像素。

我希望这个可以帮助你。

对于dynamic单元格,在UITableView上设置的rowHeight总是覆盖单个单元格的rowHeight

这种行为是IMO,一个错误。 任何时候你必须在两个地方pipe理你的用户界面,这很容易出错。 例如,如果更改故事板中的单元格大小,则必须记住在heightForRowAtIndexPath:更改它们。 直到苹果修复这个bug之前,当前最好的解决方法是覆盖heightForRowAtIndexPath:但是使用故事板中的实际原型单元来确定高度,而不是使用幻数 。 这是一个例子:

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { /* In this example, there is a different cell for the top, middle and bottom rows of the tableView. Each type of cell has a different height. self.model contains the data for the tableview */ static NSString *CellIdentifier; if (indexPath.row == 0) CellIdentifier = @"CellTop"; else if (indexPath.row + 1 == [self.model count] ) CellIdentifier = @"CellBottom"; else CellIdentifier = @"CellMiddle"; UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; return cell.bounds.size.height; } 

这将确保您的原型单元格高度的任何更改将在运行时自动获取,您只需要在一个地方pipe理您的用户界面:故事板。

我已经构build了各种答案/评论提示的代码,以便使用原型单元格的故事板。

此代码:

  • 不要求单元格高度设置在故事板中显而易见的地方以外的任何位置
  • 出于性能原因caching高度
  • 使用通用函数获取索引path的单元标识符以避免重复的逻辑

感谢Answerbot,Brennan和lensovet。

 - (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath { NSString *cellIdentifier = nil; switch (indexPath.section) { case 0: cellIdentifier = @"ArtworkCell"; break; <... and so on ...> } return cellIdentifier; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath]; static NSMutableDictionary *heightCache; if (!heightCache) heightCache = [[NSMutableDictionary alloc] init]; NSNumber *cachedHeight = heightCache[cellIdentifier]; if (cachedHeight) return cachedHeight.floatValue; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; CGFloat height = cell.bounds.size.height; heightCache[cellIdentifier] = @(height); return height; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; <... configure cell as usual...> 

实际上有两个地方你需要改变行高,首先是单元格(你已经改变了),现在select表格视图,并检查大小检查器

我认为这是一个错误。

尝试调整高度,而不是通过实用工具检查器,但直接通过鼠标拖动故事板。

我用这个方法解决了这个问题。

如果你使用的是swift,就像这样使用。 不要使用storyboard来select行高。 以这种方式编程设置表行高度,

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.row == 0 || indexPath.row == 1{ let cell = self.tableView.dequeueReusableCellWithIdentifier("section1", forIndexPath: indexPath) as! Section1TableViewCell self.tableView.rowHeight = 150 cell.label1.text = "hiiiiii" cell.label2.text = "Huiiilllllll" return cell } else { let cell = self.tableView.dequeueReusableCellWithIdentifier("section2", forIndexPath: indexPath) as! Section2TableViewCell self.tableView.rowHeight = 60 cell.label3.text = "llll" return cell } } 

在XML视图中打开故事板,并尝试编辑wanted元素的rowHeight属性。

它为我工作时,我试图为我的原型行设置自定义rowHeight。 这不是通过检查工作,但通过XML工作。

你可以从storyboard获得UITableviewCell的高度(在UITableviewController – 静态单元格中)。

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat height = [super tableView:tableView heightForRowAtIndexPath:indexPath]; return height; } 

您可以使用具有自定义height原型cells ,然后调用cellForRowAtIndexPath:并返回其frame.height 。:。

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; return cell.frame.size.height; } 

如果你想设置一个静态行高,你可以这样做:

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 120; } 

我最近一直在与此搏斗。 我的问题是上面使用heightForRowAtIndexPath:方法发布的解决scheme将适用于模拟器中的iOS 7.1,但只是简单地切换到iOS 8.1,完全搞砸了结果。

我开始阅读更多关于自我尺寸的细胞(在iOS 8中介绍,在这里阅读 )。 很显然,使用UITableViewAutomaticDimension将有助于在iOS 8中。我尝试使用该技术,并删除了使用heightForRowAtIndexPath:瞧,它现在在iOS 8中工作完美。 但是,然后iOS 7不是。 我该怎么办? 我需要heightForRowAtIndexPath: iOS 7,而不是iOS 8。

这里是我的解决scheme(为简洁起见而修剪),从上面的答案中找出答案@JosephH:

 - (void)viewDidLoad { [super viewDidLoad]; self.tableView.estimatedRowHeight = 50.; self.tableView.rowHeight = UITableViewAutomaticDimension; // ... } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) { return UITableViewAutomaticDimension; } else { NSString *cellIdentifier = [self reuseIdentifierForCellAtIndexPath:indexPath]; static NSMutableDictionary *heightCache; if (!heightCache) heightCache = [[NSMutableDictionary alloc] init]; NSNumber *cachedHeight = heightCache[cellIdentifier]; if (cachedHeight) return cachedHeight.floatValue; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; CGFloat height = cell.bounds.size.height; heightCache[cellIdentifier] = @(height); return height; } } - (NSString *)reuseIdentifierForCellAtIndexPath:(NSIndexPath *)indexPath { NSString * reuseIdentifier; switch (indexPath.row) { case 0: reuseIdentifier = EventTitleCellIdentifier; break; case 2: reuseIdentifier = EventDateTimeCellIdentifier; break; case 4: reuseIdentifier = EventContactsCellIdentifier; break; case 6: reuseIdentifier = EventLocationCellIdentifier; break; case 8: reuseIdentifier = NotesCellIdentifier; break; default: reuseIdentifier = SeparatorCellIdentifier; break; } return reuseIdentifier; } 

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@“8.0”)实际上来自我正在使用的一组macros定义,我发现某处(非常有帮助)。 它们被定义为:

 #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) 

对于dynamic单元格,在UITableView上设置的rowHeight总是覆盖单个单元格的rowHeight。 只要计算dynamic高度,如果行内的内容。

我能find的唯一真正的解决scheme就是这个

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = ...; // Instantiate with a "common" method you'll use again in cellForRowAtIndexPath: return cell.frame.size.height; } 

这个工作,并且不允许有一个可怕的开关/如果重复已经在StoryBoard的逻辑。 不确定的性能,但我想到达cellForRow:单元格已经initalized一样快。 当然,这里可能有附带的损失,但是在这里看起来对我来说工作得很好。

我也发布在这里: https : //devforums.apple.com/message/772464

编辑: Ortwin Gentz提醒我, heightForRowAtIndexPath:将被调用的所有单元格的TableView,不仅是可见的。 听起来合乎逻辑,因为iOS需要知道总高度才能显示右侧的滚动条。 这意味着它可能很好的小TableViews(如20单元格),但忘记了它在1000单元TableView。

另外,XML的前一个技巧:与我的第一个评论相同。 正确的价值已经在那里了。

作为评论添加,但发布作为可见性的答案:

如果最初将表视图设置为“静态单元”,然后将其更改为“dynamic原型”,似乎也会出现问题。 我有一个问题,即使代表方法heightForRowAtIndexPath被忽略。 我首先通过直接编辑故事板XML来解决这个问题,然后从头开始重新构build故事板场景,从一开始就使用dynamic原型。

鉴于我没有通过Interface Builder发现任何解决scheme,我决定使用两个dynamic单元Swift中发布一个编程解决scheme,尽pipe最初的问题是通过Interface Builder问一个解决scheme。 无论我认为这可能对堆栈溢出社区有帮助:

  import UIKit enum SignInUpMenuTableViewControllerCellIdentifier: String { case BigButtonCell = "BigButtonCell" case LabelCell = "LabelCell" } class SignInUpMenuTableViewController: UITableViewController { let heightCache = [SignInUpMenuTableViewControllerCellIdentifier.BigButtonCell : CGFloat(50), SignInUpMenuTableViewControllerCellIdentifier.LabelCell : CGFloat(115)] private func cellIdentifierForIndexPath(indexPath: NSIndexPath) -> SignInUpMenuTableViewControllerCellIdentifier { if indexPath.row == 2 { return SignInUpMenuTableViewControllerCellIdentifier.LabelCell } else { return SignInUpMenuTableViewControllerCellIdentifier.BigButtonCell } } override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return self.heightCache[self.cellIdentifierForIndexPath(indexPath)]! } ... } 

你可以做的另一件事是去你的文档大纲,select你的原型单元格嵌套的表视图。 然后在尺寸检查器上,将表格视图的“行高”更改为所需的值,并取消选中“自动”框。