记录下用VFL给tableFooterView设置约束的坑:VFL中“|”代表的是子控件,使用VFL时习惯性的设置translatesAutoresizingMaskIntoConstraints为NO,今天设置footerView为的这个属性为NO以后,导致footerView的子控件约束出错的问题:
需求:TableView的footerView上面添加两个按钮,为了做屏幕适配,通过代码给其添加约束。
约束:两个按钮的宽高相同,左右对齐,上下左右的间距为20,高度为44,宽度自适应,如下图,
屏幕快照 2016-10-28 下午8.45.04.png
步骤:
- 1.创建一个UIView类型的footerView对象,设置其高度为200,将footerView设置为tableView的tableFooterView。
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenW, 200)];
self.tableView.tableFooterView = footerView;
-
2.创建2个按钮,将其添加为footerView的子控件。
// 发消息 UIButton *sendMsgBtn= [UIButton xy_button:^(UIButton *btn) { UIColor *sendMsgBtnBackgroundColor = [UIColor colorWithRed:(51/255.0) green:(180/255.0) blue:(23/255.0) alpha:1]; [btn setBackgroundImage: [UIImage xy_imageWithColor:sendMsgBtnBackgroundColor] forState: UIControlStateNormal]; [btn setTitleColor:[UIColor whiteColor] forState: UIControlStateNormal]; [btn setTitle:@"发消息" forState: UIControlStateNormal]; btn.layer.cornerRadius = 5; btn.layer.masksToBounds = YES; [footerView addSubview: btn]; } buttonClickCallBack:^(UIButton *btn) { NSLog(@"点击了发消息"); }]; // 发视频按钮 UIButton *sendVdieoBtn = [UIButton xy_button:^(UIButton *btn) { UIColor *sendVdieoBtnBackgroundColor = [UIColor colorWithRed:(51/255.0) green:(180/255.0) blue:(23/255.0) alpha:1]; [btn setBackgroundImage: [UIImage xy_imageWithColor:sendVdieoBtnBackgroundColor] forState: UIControlStateNormal]; [btn setTitleColor:[UIColor whiteColor] forState: UIControlStateNormal]; [btn setTitle:@"视频聊天" forState: UIControlStateNormal]; btn.layer.cornerRadius = 5; btn.layer.masksToBounds = YES; [footerView addSubview:btn]; } buttonClickCallBack:^(UIButton *btn) { NSLog(@"点击了视频聊天按钮"); }];
3.将两个按钮的translatesAutoresizingMaskIntoConstraints属性设置为NO。
// self.view.translatesAutoresizingMaskIntoConstraints = NO; // 不需要设置
sendVdieoBtn.translatesAutoresizingMaskIntoConstraints = NO;
sendMsgBtn.translatesAutoresizingMaskIntoConstraints = NO;
// footerView.translatesAutoresizingMaskIntoConstraints = NO; // 不需要设置
-
4.添加约束(VFL)
NSDictionary *metris = @{@"margin": @20, @"btnHeight": @44}; NSDictionary *views = NSDictionaryOfVariableBindings(sendMsgBtn, sendVdieoBtn); [footerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[sendMsgBtn]-margin-|" options:0 metrics:metris views:views]]; [footerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[sendVdieoBtn]-margin-|" options:0 metrics:metris views:views]]; [footerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-margin-[sendMsgBtn(btnHeight)]-margin-[sendVdieoBtn(sendMsgBtn)]" options:0 metrics:metris views:views]];
注意:
- 这里不要footerView的translatesAutoresizingMaskIntoConstraints属性了,我设置footerView的这个属性为NO后,导致两个子控件的约束变为貌似针对控制器view的了,所以这里提醒下自己,如果以后发现使用VFL的约束搞不定,可以先用Masonry写以下,再思考VFL哪里出错。
以下是使用Masonry实现的代码
[sendMsgBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(footerView).mas_offset(20);
make.right.mas_equalTo(footerView).mas_offset(-20);
make.top.mas_equalTo(footerView);
make.height.mas_equalTo(44);
}];
[sendVdieoBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(sendMsgBtn);
make.right.mas_equalTo(sendMsgBtn);
make.top.mas_equalTo(sendMsgBtn.mas_bottom).mas_offset(20);
make.height.mas_equalTo(sendMsgBtn);
}];