我试图将自动布局合并到我的UITableViewHeaderFooterView子类中.该课程是非常基本的,只有两个标签.这是完整的子类:
@implementation MBTableDetailStyleFooterView static void MBTableDetailStyleFooterViewCommonSetup(MBTableDetailStyleFooterView *_self) { UILabel *rightLabel = [[UILabel alloc] init]; _self.rightLabel = rightLabel; rightLabel.translatesAutoresizingMaskIntoConstraints = NO; [_self.contentView addSubview:rightLabel]; UILabel *leftLabel = [[UILabel alloc] init]; _self.leftLabel = leftLabel; leftLabel.translatesAutoresizingMaskIntoConstraints = NO; [_self.contentView addSubview:leftLabel]; NSDictionary *views = NSDictionaryOfVariableBindings(rightLabel,leftLabel); NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[leftLabel]-(>=10)-[rightLabel]-10-|" options:0 metrics:nil views:views]; [_self.contentView addConstraints:horizontalConstraints]; // center views vertically in super view NSLayoutConstraint *leftCenterYConstraint = [NSLayoutConstraint constraintWithItem:leftLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_self.contentView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]; [_self.contentView addConstraint:leftCenterYConstraint]; NSLayoutConstraint *rightCenterYConstraint = [NSLayoutConstraint constraintWithItem:rightLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_self.contentView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]; [_self.contentView addConstraint:rightCenterYConstraint]; // same height for both labels NSLayoutConstraint *sameHeightConstraint = [NSLayoutConstraint constraintWithItem:leftLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:rightLabel attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; [_self.contentView addConstraint:sameHeightConstraint]; } + (BOOL)requiresConstraintBasedLayout { return YES; } - (id)initWithReuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithReuseIdentifier:reuseIdentifier]; MBTableDetailStyleFooterViewCommonSetup(self); return self; } @end
这个类用作tableView中的第一部分的页脚,具有2个部分.第一部分包含动态项目.第二部分只有一行,用于向第一部分添加新项目.
如果第一部分没有项目,我隐藏了脚注视图.所以当我添加第一个新项目时,我必须重新加载该部分,以便footerView出现.所有这些代码看起来像这样:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; if (indexPath.section == 1) { BOOL sectionNeedsReload = ([self.data count] == 0); // reload section when no data (and therefor no footer) was present before the add [self.data addObject:[NSDate date]]; NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:[self.data count]-1 inSection:0]; if (sectionNeedsReload) { [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic]; } else { [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } [self configureFooter:(MBTableDetailStyleFooterView *)[tableView footerViewForSection:0] forSection:0]; } } - (void)configureFooter:(MBTableDetailStyleFooterView *)footer forSection:(NSInteger)section { footer.leftLabel.text = @"Total"; footer.rightLabel.text = [NSString stringWithFormat:@"%d",[self.data count]]; } - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { MBTableDetailStyleFooterView *footer = nil; if (section == 0 && [self.data count]) { footer = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"]; [self configureFooter:footer forSection:section]; } return footer; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { CGFloat height = 0; if (section == 0 && [self.data count]) { height = 20.0f; } return height; }
没什么好想的但是,只要reloadSections:withRowAnimations:在我的tableView上被调用,它会抛出异常,因为它是“无法同时满足约束”.
在某处,tableView将翻译的自动调整大小的掩码约束添加到我的页脚.
( "<NSLayoutConstraint:0x718a1f0 H:[UILabel:0x7189130]-(10)-| (Names: '|':_UITableViewHeaderFooterContentView:0x7188df0 )>","<NSLayoutConstraint:0x7189e30 H:[UILabel:0x71892c0]-(>=10)-[UILabel:0x7189130]>","<NSLayoutConstraint:0x718a0a0 H:|-(10)-[UILabel:0x71892c0] (Names: '|':_UITableViewHeaderFooterContentView:0x7188df0 )>","<NSAutoresizingMaskLayoutConstraint:0x7591ab0 h=--& v=--& H:[_UITableViewHeaderFooterContentView:0x7188df0(0)]>" )
当我替换reloadSections:withRowAnimations:调用reloadData不添加自动调整掩码约束,一切正常.
有趣的是,异常告诉我,它试图中断约束< NSLayoutConstraint:0x7189e30 H:[UILabel:0x71892c0] - (> = 10) – [UILabel:0x7189130]>
但是当我在对configureFooter的后续调用中记录约束:forSection:该约束仍然存在,但是自动调整大小掩码约束已经消失
这些约束正是我所设定的.
( "<NSLayoutConstraint:0x718a0a0 H:|-(10)-[UILabel:0x71892c0] (Names: '|':_UITableViewHeaderFooterContentView:0x7188df0 )>","<NSLayoutConstraint:0x718a1f0 H:[UILabel:0x7189130]-(10)-| (Names: '|':_UITableViewHeaderFooterContentView:0x7188df0 )>","<NSLayoutConstraint:0x718a3f0 UILabel:0x71892c0.centerY == _UITableViewHeaderFooterContentView:0x7188df0.centerY>","<NSLayoutConstraint:0x718a430 UILabel:0x7189130.centerY == _UITableViewHeaderFooterContentView:0x7188df0.centerY>","<NSLayoutConstraint:0x718a4b0 UILabel:0x71892c0.height == UILabel:0x7189130.height>" )
这个自动调整大小面膜约束来自哪里?哪里去
我错过了什么吗?我第一次看汽车布局就像一个星期前,所以这是完全可能的.
解决方法
我有一个类似的问题,只有一个额外的标签在contentView.尝试插入
static void MBTableDetailStyleFooterViewCommonSetup(MBTableDetailStyleFooterView *_self) { _self.contentView.translatesAutoresizingMaskIntoConstraints = NO [...] }
在您的MBTableDetailStyleFooterViewCommonSetup函数的第一行.对于我来说,这与reloadSections结合使用:withRowAnimations :.
更新:
我还为contentView添加了一个新的约束来使用所有宽度:
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:nil views:@{@"contentView" : _self.contentView}]; [_self.contentView.superview addConstraints:horizontalConstraints];