我正在尝试调整表格视图中其中一个单元格的单元格高度。我正在从相关单元格的“尺寸检查器”中的“行高”设置中调整大小。当我在iPhone上运行应用程序时,单元格的默认大小设置为表格视图中的“行大小”。
如果我更改表格视图的“行大小”,则所有单元格的大小都会更改。我不想这样做,因为我只想要一个单元格的自定义大小。我看过很多帖子都有针对该问题的程序化解决方案,但如果可能的话,我更愿意通过故事板来实现。
答案 0 :(得分:291)
在动态单元格上,UITableView上设置的rowHeight
始终会覆盖单个单元格的rowHeight。
但是在静态单元格上,在单个单元格上设置的rowHeight
可以覆盖UITableView。
不确定这是不是一个错误,Apple可能会故意这样做?
答案 1 :(得分:84)
如果您使用UITableViewController,请实现此方法:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
在行的功能中,您可以选择高度。例如,
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return 100;
}
else {
return 60;
}
}
在这个例子中,第一行高度为100像素,其他行为60像素。
我希望这个可以帮到你。
答案 2 :(得分:34)
对于动态单元格,rowHeight
上设置的UITableView
始终会覆盖单个单元格rowHeight
。
这个行为是,IMO,一个bug。任何时候你必须在两个地方管理你的UI很容易出错。例如,如果您在故事板中更改单元格大小,则必须记住在heightForRowAtIndexPath:
中更改它们。在Apple修复错误之前,目前最好的解决方法是覆盖heightForRowAtIndexPath:
,但是使用故事板中的实际原型单元格来确定高度,而不是使用magic numbers。这是一个例子:
- (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;
}
这将确保在运行时自动获取原型单元格高度的任何更改,您只需在一个位置管理您的UI:故事板。
答案 3 :(得分:22)
我已经构建了各种答案/评论提示的代码,以便适用于使用原型单元的故事板。
此代码:
感谢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...>
答案 4 :(得分:20)
实际上有两个地方你需要改变行高,首先是单元格(你已经改变了) 现在选择表格视图并检查尺寸检查器
答案 5 :(得分:11)
我认为这是一个错误。
尝试不是通过实用程序检查器调整高度,而是直接在故事板上拖动鼠标。
我用这种方法解决了这个问题。
答案 6 :(得分:9)
如果您使用swift,请使用这样的方法。不要使用故事板来选择行高。以编程方式设置表行高度,
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
}
}
答案 7 :(得分:6)
在XML视图中打开故事板,尝试编辑所需元素的rowHeight
属性。
当我尝试为原型行设置自定义rowHeight时,它对我有用。 它不是通过检查员工作,而是通过XML工作。
答案 8 :(得分:6)
你可以借助以下几行从故事板中获取UITableviewCell(在UITableviewController - 静态单元格中)的高度。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height = [super tableView:tableView heightForRowAtIndexPath:indexPath];
return height;
}
答案 9 :(得分:5)
您可以将原型cells
与自定义height
一起使用,然后调用cellForRowAtIndexPath:
并返回其frame.height
。:。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self tableView:tableView
cellForRowAtIndexPath:indexPath];
return cell.frame.size.height;
}
答案 10 :(得分:4)
如果要设置静态行高,可以执行以下操作:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 120;
}
答案 11 :(得分:4)
我最近一直在努力解决这个问题。我的问题是上面使用heightForRowAtIndexPath:
方法发布的解决方案适用于模拟器中的iOS 7.1,但只需切换到iOS 8.1即可完全搞砸了结果。
我开始阅读更多关于自我调整大小的细节(在iOS 8中引入,read here)。很明显,使用UITableViewAutomaticDimension
会对iOS 8有所帮助。我尝试使用该技术并删除heightForRowAtIndexPath:
的使用,瞧,它现在在iOS 8中运行得很好。但后来iOS 7却没有。我该怎么办?对于iOS 7,我需要heightForRowAtIndexPath:
而不是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)
答案 12 :(得分:1)
对于动态单元格,UITableView上设置的rowHeight始终会覆盖单个单元格的rowHeight。如果行内的内容,只需计算动态高度。
答案 13 :(得分:1)
使用Swift 4 处理 XCode 9时出现同样的问题。
为单元格内的UI元素添加AutoLayout ,自定义单元格行高将按指定的方式相应地工作。
答案 14 :(得分:0)
作为评论添加,但作为可见性的答案发布:
如果您最初将表格视图设置为“静态单元格”,然后将其更改为“动态原型”,那么似乎也存在问题。我遇到了一个问题,即使heightForRowAtIndexPath
的委托方法被忽略了。我首先通过直接编辑故事板XML来解决它,然后最终从头开始重建故事板场景,从一开始就使用动态原型。
答案 15 :(得分:0)
鉴于我没有通过Interface Builder找到任何解决方案,我决定使用两个动态单元在 Swift 中发布一个程序化解决方案,甚至虽然最初的问题是通过Interface Builder要求解决方案。无论我认为它对Stack Overflow社区有用:
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)]!
}
...
}
答案 16 :(得分:0)
我能找到的唯一真正的解决方案是
- (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个单元格)但在1000 Cell TableView上忘记它。
此外,XML的上一个技巧:与我的第一个评论相同。正确的价值已经存在。
答案 17 :(得分:0)
您可以做的另一件事是转到文档大纲,选择嵌套原型单元格的表格视图。然后在“大小”检查器上,将表格视图“行高”更改为所需的值,并取消选中“自动”框。