我试图调整我的表格视图中的一个单元格的高度。我正在调整单元格的“大小检查器”内的“行高”设置的大小。当我在我的iPhone上运行应用程序时,单元格的默认大小设置自表格视图中的“行大小”。
如果我改变了表格视图的“行大小”,那么所有单元格的大小都会改变。我不想这样做,因为我只想为一个单元格自定义大小。我已经看到了很多关于这个问题的程序化解决方案的帖子,但如果可能的话,我更喜欢通过故事板来实现。
我试图调整我的表格视图中的一个单元格的高度。我正在调整单元格的“大小检查器”内的“行高”设置的大小。当我在我的iPhone上运行应用程序时,单元格的默认大小设置自表格视图中的“行大小”。
如果我改变了表格视图的“行大小”,那么所有单元格的大小都会改变。我不想这样做,因为我只想为一个单元格自定义大小。我已经看到了很多关于这个问题的程序化解决方案的帖子,但如果可能的话,我更喜欢通过故事板来实现。
当前回答
在动态单元格上,UITableView上设置的rowHeight总是覆盖单个单元格的rowHeight。
但是在静态单元格上,在单个单元格上设置rowHeight可以覆盖UITableView的。
不确定这是否是一个漏洞,苹果可能是故意这么做的?
其他回答
我唯一能找到的解决办法就是这个
- (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:细胞已经初始化,它是一样快。当然,这里可能会有附带损害,但看起来对我来说还行。
我还在这里发布了这个:https://devforums.apple.com/message/772464
编辑:Ortwin Gentz提醒我,heightForRowAtIndexPath:将被调用的所有单元格的TableView,而不仅仅是可见的。听起来很合理,因为iOS需要知道总的高度才能显示正确的滚动条。这意味着它可能在小的TableView(比如20个Cell)上很好,但在1000个Cell TableView上就忘了它了。
同样,前面关于XML的技巧:对我来说,与第一个注释相同。正确的值已经在那里了。
在动态单元格上,UITableView上设置的rowHeight总是覆盖单个单元格的rowHeight。
但是在静态单元格上,在单个单元格上设置rowHeight可以覆盖UITableView的。
不确定这是否是一个漏洞,苹果可能是故意这么做的?
作为评论添加,但作为可见性的答案发布:
如果最初将表视图设置为“静态单元格”,然后将其更改为“动态原型”,似乎也会出现问题。我有一个问题,甚至委托方法heightForRowAtIndexPath被忽略。我首先通过直接编辑故事板XML来解决这个问题,然后最终从头开始重新构建故事板场景,从一开始就使用动态原型。
我已经构建了各种答案/注释提示的代码,以便这适用于使用原型单元格的故事板。
这段代码:
不需要单元格高度设置在任何地方除了明显的地方在故事板 出于性能原因缓存高度 使用公共函数获取索引路径的单元格标识符,以避免重复逻辑
感谢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...>
我最近一直在纠结这个问题。我的问题是上面发布的解决方案使用highightforrowatindexpath:方法可以在模拟器中的iOS 7.1中工作,但如果简单地切换到iOS 8.1,就会完全搞砸结果。
我开始阅读更多关于自调整单元格的内容(在iOS 8中引入,阅读这里)。很明显,在iOS 8中使用UITableViewAutomaticDimension会有所帮助。我尝试使用这种技术并删除了highightforrowatindexpath:瞧,它现在在iOS 8中完美地工作了。但是iOS 7并没有。我该怎么办呢?我需要heightForRowAtIndexPath: iOS 7,而不是iOS 8。
以下是我的解决方案(为简洁起见进行了修改),借鉴了@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”)实际上来自我正在使用的一组宏定义,这是我在某处找到的(非常有用)。它们被定义为:
#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)