为啥我的自定义 UITableViewCell 宽度在初始加载时不正确?

Posted

技术标签:

【中文标题】为啥我的自定义 UITableViewCell 宽度在初始加载时不正确?【英文标题】:Why is my custom UITableViewCell width incorrect on initial load?为什么我的自定义 UITableViewCell 宽度在初始加载时不正确? 【发布时间】:2015-04-28 18:41:06 【问题描述】:

这个问题有两个规定。它不能通过任何一个来解决)

- (void)viewDidAppear:(BOOL)animated  
    ...
    [self.tableView reloadData]

或 b)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
...
    [cell layoutIfNeeded];

a) A 不起作用,因为调用 viewDidAppear 时单元格的数据不存在。数据是在后台线程中从服务器异步获取的,需要一些时间来检索。此外,此调用的完成块中的[self.tableView reloadData] 也不起作用。 (是的,reloadData 语句正在完成它的工作并在主线程上执行)

b) 这永远不需要从 cellForRowAtIndexPath 调用,这是一个更大问题的警告信号。虽然调用[cell layoutIfNeeded] 正在解决宽度问题,但它的成本很高。每次通话 6-10 毫秒。 cellForRowAtIndexPath 必须保持在 13.67ms (1/60fps) 以下,否则会出现性能问题。此调用会导致大量性能问题,也不是正确的解决方案。

现在,关于这个问题:

1) 正如您在我的 nib 中看到的 [http://i.imgur.com/oa8xZvB.png],我的 Cell 和 ContentView 的宽度都是 321。

2) 我有以下代码 cellForRowAtIndexPath

NSLog(@"TableView     Width: %f", self.tableView.frame.size.width);
NSLog(@" ContentView   Width: %f", cell.contentView.frame.size.width);
NSLog(@"  ContainerView Width: %f", cell.containerView.frame.size.width);
NSLog(@"   CardView      Width: %f", cell.cardView.frame.size.width);

3) 初始加载后,这些是结果/输出一直向下滚动并再次备份 3 次。

2015-04-28 11:24:10.026 Roto Forum[82016:683164] TableView     Width: 375.000000
2015-04-28 11:24:10.026 Roto Forum[82016:683164]  ContentView   Width: 321.000000
2015-04-28 11:24:10.027 Roto Forum[82016:683164]   ContainerView Width: 345.000000
2015-04-28 11:24:10.027 Roto Forum[82016:683164]    CardView      Width: 305.000000
...
... 3 more sets exactly like these removed for brevity ...
...
2015-04-28 11:24:12.867 Roto Forum[82016:683164]  ContentView   Width: 321.000000
2015-04-28 11:24:12.867 Roto Forum[82016:683164]   ContainerView Width: 345.000000
2015-04-28 11:24:12.867 Roto Forum[82016:683164]    CardView      Width: 305.000000
2015-04-28 11:24:12.901 Roto Forum[82016:683164] TableView     Width: 375.000000
2015-04-28 11:24:12.901 Roto Forum[82016:683164]  ContentView   Width: 375.000000
2015-04-28 11:24:12.901 Roto Forum[82016:683164]   ContainerView Width: 383.000000
2015-04-28 11:24:12.901 Roto Forum[82016:683164]    CardView      Width: 343.000000
...
... 37 more sets exactly like these removed for brevity ...
...
2015-04-28 11:24:20.716 Roto Forum[82016:683164] TableView     Width: 375.000000
2015-04-28 11:24:20.716 Roto Forum[82016:683164]  ContentView   Width: 375.000000
2015-04-28 11:24:20.716 Roto Forum[82016:683164]   ContainerView Width: 383.000000
2015-04-28 11:24:20.716 Roto Forum[82016:683164]    CardView      Width: 343.000000

此代码输出的前 5 组如下所示...

2015-04-28 11:24:10.026 Roto Forum[82016:683164] TableView     Width: 375.000000
2015-04-28 11:24:10.026 Roto Forum[82016:683164]  ContentView   Width: 321.000000
2015-04-28 11:24:10.027 Roto Forum[82016:683164]   ContainerView Width: 345.000000
2015-04-28 11:24:10.027 Roto Forum[82016:683164]    CardView      Width: 305.000000

最后 40 个看起来像这样......

2015-04-28 11:24:20.716 Roto Forum[82016:683164] TableView     Width: 375.000000
2015-04-28 11:24:20.716 Roto Forum[82016:683164]  ContentView   Width: 375.000000
2015-04-28 11:24:20.716 Roto Forum[82016:683164]   ContainerView Width: 383.000000
2015-04-28 11:24:20.716 Roto Forum[82016:683164]    CardView      Width: 343.000000

最初加载的单元格的 ContentView/ContainerView/CardView 宽度值为 321/345/305,而所有后续加载该单元格或任何其他单元格的宽度值为 375/383/343。什么给了?

这些是最初加载的,因为它们从一开始就可以在表格视图中查看。最后 40 是我每次上下滚动表格视图时得到的。为什么我在初始加载时会得到这些不正确的宽度?

============================ 编辑:=============== ============

根据第一条评论的要求添加一些代码

heightForRowAtIndexPath:未实现,因为这是一个 ios8 Self Sizing Cell。

cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *cellIdentifier = @"MyCardCell";
    MyCardCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    Question *question = [self.questions objectAtIndex:indexPath.row];

    cell.title.text = question.questionTitle;
    cell.subtitle.text = question.questionText;
    cell.username.text = question.userName;

    NSLog(@"TableView     Width: %f", self.tableView.frame.size.width);
    NSLog(@" ContentView   Width: %f", cell.contentView.frame.size.width);
    NSLog(@"  ContainerView Width: %f", cell.containerView.frame.size.width);
    NSLog(@"   CardView      Width: %f", cell.cardView.frame.size.width);

    return cell;

ViewController.h

@property UINib *myCardCellNib;

ViewController.m

viewDidLoad:

self.myCardCellNib = [UINib nibWithNibName:@"MyCardCellTableViewCell" bundle:nil];
[self.tableView registerNib:self.myCardCellNib forCellReuseIdentifier:@"MyCardCell"];
[self.tableView setEstimatedRowHeight:237.0];
[self.tableView setRowHeight:UITableViewAutomaticDimension];

表格视图单元格初始化:

#import "MyCardCellTableViewCell.h"

//managers
#import "FFFColorManager.h"

@implementation MyCardCellTableViewCell

- (void)awakeFromNib 
    [self initializeAppearance];


- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
    [super setSelected:selected animated:animated];


#pragma mark - Private

- (void)initializeAppearance 
    [self initializeFonts];
    [self initializeColors];


- (void)initializeFonts 
    self.title.font = [UIFont fontWithName:@"Roboto-Regular" size:14.0];
    self.subtitle.font = [UIFont fontWithName:@"Roboto-Regular" size:12.0];
    self.username.font = [UIFont fontWithName:@"Roboto-Light" size:10.0];


- (void)initializeColors 
    self.respondLabel.backgroundColor = [[FFFColorManager sharedManager] colorForApplicationColorIdentifier:ApplicationColorIdentifierQuestionCardSectionRespondBackground];
    self.containerView.backgroundColor = [[FFFColorManager sharedManager] colorForApplicationColorIdentifier:ApplicationColorIdentifierTableViewBackground];

    UIColor *cardForegroundColor = [[FFFColorManager sharedManager] colorForApplicationColorIdentifier:ApplicationColorIdentifierQuestionCard];
    self.title.backgroundColor = cardForegroundColor;
    self.subtitle.backgroundColor = cardForegroundColor;


@end

【问题讨论】:

发布你的 heightforRow、cellForRow 和 tavleview 和 tableviewcell 初始化 @ArunGupta 我将它们添加为我的问题的编辑。知道发生了什么吗? 【参考方案1】:

解决了。

问题是我对自定义单元类的 initializeFonts 调用。更改字体大小会更改单元格的高度。

【讨论】:

很好地解决了这个问题!你最终是如何解决这个问题的?将 initializeFonts 移到别处,直接在 XIB 中设置?

以上是关于为啥我的自定义 UITableViewCell 宽度在初始加载时不正确?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的自定义 UITableViewcell 没有显示?

在自定义UITableViewCell中保持UIImageView的宽高比

为啥我的自定义 UITableViewCell 宽度在初始加载时不正确?

为啥我的自定义单元格仅在用户移开手指时突出显示?

为啥在我的自定义 UIView 类中没有调用 init(frame: CGRect)?

如何阻止我的自定义 UITableViewCell backgroundImage 可拉伸?