我有一个简单的演示 AutoSizing UITableView 项目,如下所示: 当你点击tableview单元格时,单元格的红色子视图的高度约束会变大(从原来的60到100)并调用reloadData。
#import "ViewController.h"
#import "TestCell.h"
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic,assign) NSInteger value;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableView.dataSource = self;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.delegate = self;
[self.tableView registerNib:[UINib nibWithNibName:@"TestCell" bundle:nil] forCellReuseIdentifier:@"TestCell"];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TestCell* cell = (TestCell*)[tableView dequeueReusableCellWithIdentifier:@"TestCell" forIndexPath:indexPath];
cell.value = self.value;
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.value += 1;
[self.tableView reloadData];
}
和细胞:
#import "TestCell.h"
@interface TestCell()
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;//red view's height constraint
@end
@implementation TestCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)setValue:(NSInteger)value
{
if (value > 1)
{
self.heightConstraint.constant = 100;
}
[self setNeedsLayout];
[self setNeedsUpdateConstraints];
}
@end
但是当我调用 reloadData 时,会出现这样的约束中断警告
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x6000021279d0 UIView:0x10d615680.height == 100 (active)>",
"<NSLayoutConstraint:0x600002126f80 V:[UIView:0x10d615680]-(10)-| (active, names: '|':UITableViewCellContentView:0x10d6154c0 )>",
"<NSLayoutConstraint:0x600002127070 V:|-(0)-[UIView:0x10d615680] (active, names: '|':UITableViewCellContentView:0x10d6154c0 )>",
"<NSLayoutConstraint:0x6000021277a0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x10d6154c0.height == 70 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000021279d0 UIView:0x10d615680.height == 100 (active)>
这里有一个 UIView-Encapsulated-Layout-Height 约束,我认为这个约束是布局系统在第一次布局时生成的。
如果我之后调用reloadData,布局仍然会使用之前生成的单元格高度约束(高度:70),所以如果我将子视图的高度更改为100,这将产生冲突。
我认为系统生成的高度约束有时应该是无效的。有办法做到这一点吗?
当表视图布置其单元格时,单元格继承 height 约束。如果您执行某些操作来更改单元格的视图约束(例如更改红色视图的高度常量),则会出现自动布局冲突直到下一次布局通过。
假设您的
redView
对单元格的 contentView
底部有底部约束...
将该底部约束的
Priority
更改为 999
。这将消除自动布局的抱怨。