EasyIOS中AutoLayoutCell加载动态图片的问题

EasyIOS框架中 AutoLayoutCell  确实是很好用的 。

今天在使用AutoLayoutCell完善一个项目的时候遇到一个问题,当cell在加载通过网络数据请求到的图片的时候,该如何给渲染该图片的UIImageView添加约束。

理论上讲大家都懂:在cell重用的时候,移除UIImageView上旧的约束,添加新约束。理论当然是对的。

先大概讲下我用来测试这个想法用到的案例:

首先,用EasyIOS创建一个项目,自定义一个Scene,里面添加一个tableView,这个tableView当然是EasyIOS里面的ALTableView类型。然后自定义Cell,Cell的模型如下

#import <UIKit/UIKit.h>

@interface CommentCell : UITableViewCell
@property(strong,nonatomic)UIImageView *avator;//这个就是用来显示动态图片的UIImageView
@property(strong,nonatomic)UILabel *nicknameLabel;
@property(strong,nonatomic)UILabel *timeLabel;
@property(strong,nonatomic)UILabel *contentLabel;

- (void)setViewLayout;
@end

//
//  CommentCell.m
//  ledaibao.ios
//
//  Created by 王宏 on 15/2/9.
//  Copyright (c) 2015年 ledaibao. All rights reserved.
//

#import "CommentCell.h"

@implementation CommentCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if(self){
        [self setBackgroundColor:[UIColor flatWhiteColor]];
        _avator = [UIImageView new];
        _avator.contentMode = UIViewContentModeScaleAspectFill;
        _avator.layer.cornerRadius = 10;
        _avator.layer.masksToBounds = YES;
        _avator.clipsToBounds = YES;
        [self.contentView addSubview:_avator];
        
        _nicknameLabel = [UILabel new];
        [_nicknameLabel setFont:[UIFont systemFontOfSize:10.0f]];
        [_nicknameLabel setTextColor:[UIColor colorWithRed:0.000 green:0.502 blue:1.000 alpha:0.570]];
        [self.contentView addSubview:_nicknameLabel];
        
        
        _timeLabel = [UILabel new];
        [_timeLabel setFont:[UIFont systemFontOfSize:10.0f]];
        [_timeLabel setTextColor:[UIColor lightGrayColor]];
        [_timeLabel setNumberOfLines:1];
        [self.contentView addSubview:_timeLabel];
        
        UIView *line = [[UIView alloc]init];
        [self.contentView addSubview:line];
        [line setBackgroundColor:[UIColor colorWithWhite:0.767 alpha:0.440]];
        [line alignLeading:@"20" trailing:@"-20" toView:line.superview];
        [line constrainHeight:@"1"];
        [line alignBottomEdgeWithView:line.superview predicate:@"-1"];
        
        _contentLabel = [UILabel new];
        [_contentLabel setFont:[UIFont systemFontOfSize:13.0f]];
        [_contentLabel setTextColor:[UIColor blackColor]];
        [_contentLabel setNumberOfLines:0];
        [self.contentView addSubview:_contentLabel];
        
        [self setViewLayout];
        
    }
    return self;
}



- (void)setViewLayout
{
    //[_avator constrainWidth:@"20" height:@"20@999"];
    [_avator constrainWidth:@"20"];
    [_avator alignTop:@"10" leading:@"20" toView:_avator.superview];
    
    [_nicknameLabel alignBottomEdgeWithView:_avator predicate:nil];
    [_nicknameLabel constrainLeadingSpaceToView:_avator predicate:@"10"];
    [_nicknameLabel constrainHeight:@"20"];
    
    [_timeLabel alignBottomEdgeWithView:_avator predicate:nil];
    [_timeLabel alignTrailingEdgeWithView:_timeLabel.superview predicate:@"-20"];
    [_timeLabel constrainHeight:@"20"];
    
    [_contentLabel constrainTopSpaceToView:_avator predicate:@"10"];
    [_contentLabel alignLeading:@"20" trailing:@"-20" toView:_contentLabel.superview];
    [_contentLabel alignBottomEdgeWithView:_contentLabel.superview predicate:@"-10"];
}

-(void)prepareForReuse
{
    [super prepareForReuse];
//    NSArray *constraints = self.avator.constraints;
//      NSLog(@"111constraints:%@",constraints);
//    for(NSLayoutConstraint *l in constraints)
//    {
//        if(l.priority == 999)
//        {
//            [_avator removeConstraint:l];
//            NSLog(@"111111:%@",_avator.constraints);
//        }
//        
//    }
}


@end
.m文件这样已经相当详细了,看- (void)prepareForReuse里面的注释掉的代码,移除旧的约束,然后在cell生成的时候,添加新约束,理论上是没有问题的。但是,关键是这个但是,测试的时候 模拟器显示的时候,cell的高度明显不够  ,看图

下面贴一下我生成cell的过程,

- (void)tableView:(UITableView *)tableView configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    CommentCell *commentCell = (CommentCell *)cell;
    Comment *comment = [self.commentSceneModel.commentList.commentArray objectAtIndex:indexPath.row];
    [commentCell.avator sd_setImageWithURL:[NSURL URLWithString:comment.avator] placeholderImage:[UIImage imageNamed:@"avator"]];
    
    NSArray *heightArray = @[@"30",@"40",@"150",@"60",@"10",@"120",@"55",@"14",@"88",@"168"];
    
    
    NSString *heightString = [NSString stringWithFormat:@"%@@999",[heightArray objectAtIndex:indexPath.row]];
    
//    NSArray *constraints = commentCell.avator.constraints;
//    for(NSLayoutConstraint *l in constraints)
//    {
//        if(l.priority == 999)
//        {
//            [commentCell.avator removeConstraint:l];
//        }
//        
//    }
    [commentCell.avator constrainHeight:heightString];
    NSLog(@"111111:%@",commentCell.avator.constraints);
    
    [commentCell.contentLabel setText:comment.content];
    [commentCell.nicknameLabel setText:comment.nickname];
    NSString *timestamp = [TimeFormat timestamp:comment.createTime];
    [commentCell.timeLabel setText:timestamp];
}

为了起到测试效果,我将avator定宽,高度安排数组里面那些高度来模拟动态数据。理论上是ok的 ,但是  问题出在哪里呢,研究了一下午,掰开EasyIOS源码,
找到ALTableViewCellFactory这个文件,找到这里



你发现了什么,是的  EasyIOS框架的ALTableViewCellFactory在计算高度的时候先渲染数据再计算高度,它计算高度的时候自始至终只用了一个cell,所以导致一个问题:在我第一次添加动态图片的约束的时候这个约束存在,第二次计算高度的时候,又添加了一个新的约束条件,而老的约束依然存在,因为计算高度的时候,并没有执行cell的回收方法,所以在prepareForReuse里面去掉旧的约束是不对的,虽然产生的cell是可以用的 但是,计算出来的高度有问题。所以只能在渲染cell内容的时候 ,先判断cell中avator的旧的约束将其删除,后添加新约束,每次都是如此.这样的话:第一,在计算cell高度的时候,能保证cell的avator没有旧约束的干扰,正确的计算cell的高度。第二,生成cell的时候,当cell属于回收cell,可以省略prepareForReuse中对于旧约束的判断,直接写在cell渲染阶段,保证cell约束的完整性.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值