gpt4 book ai didi

ios - 具有自动布局和部分重新加载的 UITableViewHeaderFooterView 子类不能很好地协同工作

转载 作者:IT王子 更新时间:2023-10-29 08:05:11 31 4
gpt4 key购买 nike

我正在尝试将自动布局合并到我的 UITableViewHeaderFooterView 子类中。该类(class)非常基础,只有两个标签。这是完整的子类:

@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

此类用作具有 2 个部分的 tableView 中第一部分的页脚。第一部分包含动态项目。第二部分只有一行,用于向第一部分添加新项目。

如果第一部分中没有项目,我会隐藏 footerView。因此,当我添加第一个新项目时,我必须重新加载该部分,以便出现 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:0x7189e30 H:[UILabel:0x71892c0]-(>=10)-[UILabel:0x7189130]>",
"<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>"
)

这个自动调整大小的 mask 约束从何而来?它去哪儿了?

我错过了什么吗?我第一次研究自动布局是在一周前,所以这完全有可能。

最佳答案

iOS 9 的工作解决方案

在您的 UITableViewHeaderFooterView 子类中放置以下代码。

- (void)setFrame:(CGRect)frame {
if (frame.size.width == 0) {
return;
}

[super setFrame:frame];
}

解释:

tableview 处理标题 View 的布局,它通过手动操作框架来实现(是的,即使打开了自动布局)。

如果您检查页眉/页脚 View 上的宽度约束,则有两种,一种包含在父 View ( TableView )中的宽度,一种包含在页眉/页脚 View 本身中的宽度。

包含在 super View 上的约束是一个 NSAutoresizingMaskLayoutConstraint,这是 TableView 依赖于框架来操作标题的赠品。在标题 View 上将 translatesAutoresizingMaskIntoConstraints 切换为 NO 会影响其外观,这是另一个赠品。

似乎在某些情况下,这些页眉/页脚 View 的框架宽度会更改为零,对我而言,这是在插入行并重用页眉 View 时发生的。我的猜测是,在 UITableView 代码的某处,通过以零宽度开始帧来为动画做准备,即使您没有使用动画也是如此。

此解决方案应该运行良好,不会影响滚动性能。

关于ios - 具有自动布局和部分重新加载的 UITableViewHeaderFooterView 子类不能很好地协同工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17581550/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com