故事板中的自定义单元行高度设置没有响应
我正在尝试调整我的表格视图中的一个单元格的单元格高度。 我从正在讨论的单元格的“大小检查器”中的“行高”设置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你的原型单元格嵌套的表视图。 然后在尺寸检查器上,将表格视图的“行高”更改为所需的值,并取消选中“自动”框。
- 有没有办法要求用户访问相机访问后,他们已经否认了iOS 8?
- 调整UIColor的alpha
- 如何“在malloc_error_break中设置一个断点来debugging”
- 如何使UILabel在故事板(或界面生成器)中自动生成文本,而不是以编程方式
- iTunes Connect提交代码签名授权错误Xcode 8
- 有清除iPhone模拟器caching比删除其目录更快/更好的方法吗?
- 有没有办法让NSUserDefaults中的所有值?
- Xcode故事板警告:在当前configuration中closures约束引用项目。 closures当前configuration中的这个约束
- 键盘出现快捷时移动文本框