新手求助:为什么layoutSubview方法不调用?

Mr_cyz 2014-10-03 05:13:09

之前写一个仿瀑布流demo的时候在tableView中添加子控件,由于tableview的复用机制,下拉出新的cell的时候子控件不会调用layoutSubview方法,于是上网学习发现需要在cell中强制让子控件刷新,即调用子控件item的layoutSubview方法。当时问题也确实解决了,于是借这次做电子书项目将其整理成了博客:http://blog.csdn.net/u013604612/article/details/39578683。

但是这次结果下拉书架(tableview)的时候发现有重复数据,按照之前了解,是tableview的cell在复用时子控件没有调用layoutSubview方法。在子控件的layoutSubview方法中打断点,下拉的时候确实没有被中断。
在cell的layoutSubview方法中调用子控件item的setNeedsLayout方法或者是layoutIfNeeded方法都没有用。为什么?

//cell的layoutSubview方法
- (void)layoutSubviews
{
[super layoutSubviews];

for (int i = 0; i < self.booksGroup.count; i++) {
CYZBookItemView *item = (CYZBookItemView *)[self.contentView viewWithTag:100 + i];
item.frame = CGRectMake(kHorizontalEdge + (kHorizontalEdge + 80) * i, kVerticalEdge, 80, 150);
item.hidden = NO; //有数据的item不隐藏
item.bookModel = [self.booksGroup objectAtIndex:i];
[self addSubview:item];

//如果不添加以下方法,那么在cell复用时将不会调用子视图的layoutSubview方法,这样数据就无法更新了。
[item setNeedsLayout];
[item layoutIfNeeded];
}
}


//item的layoutSubview方法
- (void)layoutSubviews
{
[super layoutSubviews];

if (self.bookModel.isFromNative) {
UIImage *image = [UIImage imageNamed:[self.bookModel.images objectForKey:@"small"]];
if (image) {
[self.bookImage setBackgroundImage:image forState:UIControlStateNormal];
} else {
[self.bookImage setBackgroundImage:[UIImage imageNamed:@"default_book.png"] forState:UIControlStateNormal];
}
} else {
NSLog(@"%@", [NSURL URLWithString:[self.bookModel.images objectForKey:@"small"]]);
[self.bookImage setImageWithURL:[NSURL URLWithString:[self.bookModel.images objectForKey:@"small"]] placeholderImage:[UIImage imageNamed:@"default_book.png"]];
}

self.bookName.text = self.bookModel.title;
}


连layoutIfNeeded都没有用
...全文
146 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Mr_cyz 2014-10-07
  • 打赏
  • 举报
回复
好吧,虽然木有人鸟俺,不过俺还是自己解决了发上来供需要的人参考吧。
static NSString *cellId = @"CYZBookShelfViewCell";
    CYZBookCell *cell = (CYZBookCell *)[tableView dequeueReusableCellWithIdentifier:cellId];
    
    if (cell == nil) {
        cell = [[CYZBookCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }
    
    cell.booksGroup = [self.bookGroup2D objectAtIndex:indexPath.row];
    
    return cell;
在cell协议方法中,用deque方法取cell,如果为nil则将调用initWithStyle:reuseIdentifier:方法初始化cell。而自定义的cell正是将初始化方法加在了这里面。我所谓的初始化,是指将子视图item加到cell.contentView中并为之设tag值。而当deque方法不再返回nil的时候,此时便不再调用initWithStyle:reuseIdentifier:方法了,奇怪的是,这个时候对重用的cell,用[cell.contentView viewWithTag:] 方法取不到item视图了。之前运行地挺好,ios8之后就不行了。不过ios在取cell前会调用prepareForReuse方法。所以既然cell上有重复视图,并且cell没有初始化(添加子视图),那就在这个方法中处理即可。注意不要忘了super一下。
- (void)prepareForReuse
{
    [super prepareForReuse];

    [self removeAllSubviews];
    [self p_initView];
}

29,031

社区成员

发帖
与我相关
我的任务
社区描述
主要讨论与iOS相关的软件和技术
社区管理员
  • iOS
  • 大熊猫侯佩
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧