自动布局(FDTemplateLayoutCell的使用)

今天看到了@SUNNYXX大神的博客,其中有一篇优化UITableViewCell高度计算的那些事讲了FDTemplateLayoutCell,并且与其它两个布局方法做了对比,好处显而易见(最低适配iOS6、运行效率更高)。分别是iOS6的-systemLayoutSizeFittingSize:的API和iOS8的self-sizing cell(estimatedRowHeight、UITableViewAutomaticDimension)方法。上面两个方法之前也在博客中写过。
作为一个开发还没到一年的人,@SUNNYXX大神、喵神等都是学习的榜样,各种崇拜。
不同与Xib+FDTemplateLayoutCell的布局方法,我用的是Masonry+FDTemplateLayoutCell,运行时总是有很多约束冲突,对于原因暂时还不知道。
ViewController

#import "ViewController.h"
#import "CustomCell.h"
#import "Masonry.h"
#import "UITableView+FDTemplateLayoutCell.h"
#import "CustomModel.h"
#import "MHPrettyDate.h"

typedef NS_ENUM(NSUInteger, HTSimulatedCacheModel) {
    HTSimulatedCacheModelNone=0,
    HTSimulatedCacheModelCacheByIndexpath,
    HTSimulatedCacheModelCacheByKey
};


#define COMMON_COLOR            [UIColor colorWithRed:0/255.0f green:0/255.0f blue:107/255.0f alpha:1.0]


#define REUSEID      @"CustomCellId"

@interface ViewController () <UITableViewDataSource,UITableViewDelegate,UIActionSheetDelegate>

//@property(nonatomic,retain) UIRefreshControl   *kRefreshControl;
@property(nonatomic,retain) UISegmentedControl *kSegmentedControl;
@property(nonatomic,retain) UITableView        *kTabelView;
@property(nonatomic,retain) NSMutableArray     *kDataSource;


@end

@implementation ViewController

#pragma mark - Life Cycle

- (void)viewDidLoad {
    [super viewDidLoad];
    [self uiConfig];
    [self buildTestDataThen:^{
        [self.kTabelView reloadData];
         NSLog(@"count=%ld",self.kDataSource.count);
    }];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

#pragma mark - UITableViewDataSource

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return [self.kDataSource count];
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    NSArray *tempArr=[self.kDataSource objectAtIndex:section];
    return [tempArr count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    CustomCell *cell=[tableView dequeueReusableCellWithIdentifier:REUSEID forIndexPath:indexPath];
    [self configureCell:cell atIndexpath:indexPath];
    return cell;
}

-(void)configureCell:(CustomCell *)cell atIndexpath:(NSIndexPath *)indexPath{
    cell.fd_enforceFrameLayout=NO;
    if (indexPath.row%2==0) {
        cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
    }else{
        cell.accessoryType=UITableViewCellAccessoryCheckmark;
    }
    NSArray *tempArr=[self.kDataSource objectAtIndex:indexPath.section];
    [cell setModel:[tempArr objectAtIndex:indexPath.row]];
}

#pragma mark - UITableViewDelegate

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    HTSimulatedCacheModel model=self.kSegmentedControl.selectedSegmentIndex;
    switch (model) {
        case HTSimulatedCacheModelNone:
            return [tableView fd_heightForCellWithIdentifier:REUSEID configuration:^(id cell) {
                [self configureCell:cell atIndexpath:indexPath];
            }];
        case HTSimulatedCacheModelCacheByIndexpath:
            return [tableView fd_heightForCellWithIdentifier:REUSEID cacheByIndexPath:indexPath configuration:^(id cell) {
                [self configureCell:cell atIndexpath:indexPath];
            }];
        case HTSimulatedCacheModelCacheByKey:
            return [tableView fd_heightForCellWithIdentifier:REUSEID cacheByKey:[NSString stringWithFormat:@"key:%ld",indexPath.row] configuration:^(id cell) {
                [self configureCell:cell atIndexpath:indexPath];
            }];
        default:
            break;
    }
}

//-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
//    if (editingStyle==UITableViewCellEditingStyleDelete) {
//        NSMutableArray *tempArr=[self.kDataSource objectAtIndex:indexPath.section];
//        [tempArr removeObjectAtIndex:indexPath.row];
//        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
//    }
//}
//
//-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
//    return @"删除";
//}

//或者
- (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewRowAction *action=[UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        NSMutableArray *tempArr=[self.kDataSource objectAtIndex:indexPath.section];
        [tempArr removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }];
    action.backgroundColor=COMMON_COLOR;
    return @[action];
}

#pragma mark - UIActionSheetDelegate

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
    SEL selectors[]={
      @selector(insertRow),
      @selector(insertSection),
      @selector(deleteSection)
    };
    if (buttonIndex<sizeof(selectors)/sizeof(SEL)) {
        void(*imp)(id,SEL)=(typeof(imp))[self methodForSelector:selectors[buttonIndex]];
        imp(self,selectors[buttonIndex]);
    }
}

#pragma mark - Private Method
//模拟异步请求  然后回调
-(void)buildTestDataThen:(void(^)(void))then{
     [self.kDataSource removeAllObjects];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSMutableArray *tempArr=[[NSMutableArray alloc] init];
        for (int i=0; i<20; i++) {
            [tempArr addObject:[self getRandomModelWithIndex:i]];
        }
        [self.kDataSource addObject:tempArr];
            //回调
        dispatch_sync(dispatch_get_main_queue(), ^{
            !then ? :then();
        });
    });
}

-(CustomModel *)getRandomModelWithIndex:(int)index{
    CustomModel *model=[[CustomModel alloc] init];
    model.kTitle=[NSString stringWithFormat:@"Title:%d",index];
    model.kImgName=[NSString stringWithFormat:@"%d.png",arc4random()%6+1];
    model.kContent=[self getRandomContent];
    model.kDataStr=[MHPrettyDate prettyDateFromDate:[NSDate date] withFormat:MHPrettyDateFormatWithTime];
    model.kAuthor=[NSString stringWithFormat:@"Author:%d",index];
    return model;
}

-(void)uiConfig{
    self.view.backgroundColor=[UIColor lightTextColor];
    self.title=@"CellLayoutDemo";
    UIBarButtonItem *rightItem=[[UIBarButtonItem alloc] initWithTitle:@"Action" style:UIBarButtonItemStylePlain target:self action:@selector(rightItemAction)];
    self.navigationItem.rightBarButtonItem=rightItem;

    self.edgesForExtendedLayout=UIRectEdgeNone;
    [self.view addSubview:self.kTabelView];
    self.kTabelView.tableHeaderView=self.kSegmentedControl;
    [self.kTabelView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_top).offset(10);
        make.left.right.bottom.equalTo(self.view);
    }];
}

-(NSString *)getRandomContent{
    NSInteger num=arc4random()%10+1;
    NSMutableString *mutString=[[NSMutableString alloc] init];
    while (num>0) {
        [mutString appendString:@"不要假设我知道,一切也都是为我而做,为何这么伟大."];
        num-=1;
    }
    return mutString;
}

#pragma mark - Action Method

-(void)rightItemAction{
  UIActionSheet *actionSheet=[[UIActionSheet alloc ] initWithTitle:@"Actions" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Insert a row",@"Insert a section", @"Delete a section",nil];
    [actionSheet showInView:self.view];
}

-(void)insertRow{
    if ([self.kDataSource count]==0) {
        [self insertSection];
    }else{
        NSMutableArray *tempArr=[self.kDataSource firstObject];
        [tempArr insertObject:[self getRandomModelWithIndex:0] atIndex:0];
        NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0];
        [self.kTabelView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}

-(void)insertSection{
    NSMutableArray *tempArr=[[NSMutableArray alloc] init];
    [tempArr addObject:[self getRandomModelWithIndex:0]];
    [self.kDataSource insertObject:tempArr atIndex:0];
    [self.kTabelView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
}

-(void)deleteSection{
    if ([self.kDataSource count]>0) {
        [self.kDataSource removeObjectAtIndex:0];
        [self.kTabelView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}

#pragma mark - Lazy Method

//-(UIRefreshControl *)kRefreshControl{
//    if (_kRefreshControl==nil) {
//        _kRefreshControl=[[UIRefreshControl alloc] init];
//        _kRefreshControl.tintColor=COMMON_COLOR;
//    }
//    return _kRefreshControl;
//}

-(UISegmentedControl *)kSegmentedControl{
    if (_kSegmentedControl==nil) {
        _kSegmentedControl=[[UISegmentedControl alloc] initWithItems:@[@"No Cache",@"IndexPath Cache",@"Key Cache"]];
        _kSegmentedControl.frame=CGRectMake(20, 0, self.kTabelView.frame.size.width-40, 30);
        _kSegmentedControl.tintColor=COMMON_COLOR;
        _kSegmentedControl.selectedSegmentIndex=0;
    }
    return _kSegmentedControl;
}

-(UITableView *)kTabelView{
    if (_kTabelView==nil) {
        _kTabelView=[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
        _kTabelView.backgroundColor=[UIColor lightGrayColor];
        _kTabelView.tableFooterView=[UIView new];
        _kTabelView.dataSource=self;
        _kTabelView.delegate=self;
        [_kTabelView registerClass:[CustomCell class] forCellReuseIdentifier:REUSEID];
//        _kTabelView.estimatedRowHeight=200;
//        _kTabelView.rowHeight=UITableViewAutomaticDimension;
    }
    return _kTabelView;
}

-(NSMutableArray *)kDataSource{
    if (_kDataSource==nil) {
        _kDataSource=[[NSMutableArray alloc] init];
    }
    return _kDataSource;
}

@end

CustomCell

#import "CustomCell.h"
#import "Masonry.h"

#define COMMON_COLOR            [UIColor colorWithRed:0/255.0f green:0/255.0f blue:107/255.0f alpha:1.0]
#define CUSTOM_LIGHTGRAY_COLOR  [UIColor colorWithRed:85/255.0f green:85/255.0f blue:85/255.0f alpha:1.0]
#define CUSTOM_BLUE_COLOR  [UIColor colorWithRed:140/255.0f green:170/255.0f blue:228/255.0f alpha:1.0]

@interface CustomCell ()

@property(nonatomic,retain) UILabel     *kTitleLabel,*kContentLabel,*kAuthorLabel,*kDateLabel;
@property(nonatomic,retain) UIImageView *kIconView;

@end

@implementation CustomCell

#pragma mark - Override

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self uiConfig];
    }
    return self;
}

#pragma mark - Public Method

-(void)setModel:(CustomModel *)model{
    self.kTitleLabel.text=model.kTitle;
    self.kContentLabel.text=model.kContent;
    self.kAuthorLabel.text=model.kAuthor;
    self.kDateLabel.text=model.kDataStr;
    self.kIconView.image=[UIImage imageNamed:model.kImgName];
}

#pragma mark - Private Method

-(void)uiConfig{

    self.selectionStyle=UITableViewCellSelectionStyleNone;

    [self.contentView addSubview:self.kTitleLabel];
    [self.contentView addSubview:self.kContentLabel];
    [self.contentView addSubview:self.kIconView];
    [self.contentView addSubview:self.kAuthorLabel];
    [self.contentView addSubview:self.kDateLabel];

    [self.kTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView.mas_top).offset(10);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.width.mas_equalTo(100);
        make.height.mas_equalTo(15);
    }];
    [self.kContentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.kTitleLabel.mas_bottom).offset(10);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.right.equalTo(self.contentView.mas_right).offset(-15);
    }];
//    [self.kContentLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
//    [self.kContentLabel setContentHuggingPriority:UILayoutConstraintAxisVertical forAxis:UILayoutConstraintAxisVertical];

    [self.kIconView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.kContentLabel.mas_bottom).offset(10);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.right.lessThanOrEqualTo(self.contentView.mas_right).offset(-16);
        make.bottom.equalTo(self.kAuthorLabel.mas_bottom).offset(-20);
    }];
    [self.kAuthorLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.contentView.mas_bottom).offset(-10);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.width.mas_equalTo(100);
        make.height.mas_equalTo(15);
    }];
    [self.kDateLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.height.equalTo(self.kAuthorLabel);
        make.right.equalTo(self.contentView.mas_right).offset(-20);
        make.width.mas_equalTo(60);
    }];
}

#pragma mark - Private Method

-(UILabel *)kTitleLabel{
    if (_kTitleLabel==nil) {
        _kTitleLabel=[[UILabel alloc] init];
        _kTitleLabel.textColor=COMMON_COLOR;
        _kTitleLabel.font=[UIFont boldSystemFontOfSize:16];
    }
    return _kTitleLabel;
}

-(UILabel *)kContentLabel{
    if (_kContentLabel==nil) {
        _kContentLabel=[[UILabel alloc] init];
        _kContentLabel.numberOfLines=0;
        _kContentLabel.lineBreakMode=NSLineBreakByWordWrapping;
        _kContentLabel.textColor=CUSTOM_LIGHTGRAY_COLOR;
        _kContentLabel.font=[UIFont systemFontOfSize:14];
    }
    return _kContentLabel;
}

-(UILabel *)kAuthorLabel{
    if (_kAuthorLabel==nil) {
        _kAuthorLabel=[[UILabel alloc] init];
        _kAuthorLabel.textColor=[UIColor lightGrayColor];
        _kAuthorLabel.font=[UIFont systemFontOfSize:14];
    }
    return _kAuthorLabel;
}

-(UILabel *)kDateLabel{
    if (_kDateLabel==nil) {
        _kDateLabel=[[UILabel alloc] init];
        _kDateLabel.textColor=CUSTOM_BLUE_COLOR;
        _kDateLabel.font=[UIFont systemFontOfSize:14];
        _kDateLabel.textAlignment=NSTextAlignmentRight;
    }
    return _kDateLabel;
}

-(UIImageView *)kIconView{
    if (_kIconView==nil) {
        _kIconView=[[UIImageView alloc] init];
        _kIconView.contentMode=UIViewContentModeCenter;
        _kIconView.clipsToBounds=YES;
    }
    return _kIconView;
}

@end

CustomModel

#import 

@interface CustomModel : NSObject

@property(nonatomic,copy) NSString *kTitle,*kImgName,*kContent,*kDataStr,*kAuthor;

@end

你可能感兴趣的:(自动布局(Masonry+))