Ios 具有自动布局的UITableViewCell子类如何在运行时更改约束优先级
我的故事板里有一个细胞的原型。Ios 具有自动布局的UITableViewCell子类如何在运行时更改约束优先级,ios,uitableview,autolayout,Ios,Uitableview,Autolayout,我的故事板里有一个细胞的原型。 基本上,单元分为两部分: 文本视图 图像视图 单元初始化时,其值将对象传递给单元本身。在该方法中,单元格将其元素设置为传递的值。 其主要思想是根据图像或文本的存在改变单元格布局。为此,我过度约束了UITextView和UIImageView在一侧添加了两个具有不同优先级的约束。优先级将根据传递的对象而改变。 例如,UITextView有两条虚线,它们表示具有不同优先级和不同常量值的两个约束。第一个(从LtoR读取)优先级为910,常数为156,第二个优先级为
基本上,单元分为两部分:
- 文本视图
- 图像视图
其主要思想是根据图像或文本的存在改变单元格布局。为此,我过度约束了
UITextView
和UIImageView
在一侧添加了两个具有不同优先级的约束。优先级将根据传递的对象而改变。
例如,
UITextView
有两条虚线,它们表示具有不同优先级和不同常量值的两个约束。第一个(从LtoR读取)优先级为910,常数为156,第二个优先级为900,常数为20。
在故事板编辑器中,如果我交换了2个优先级,我将从视觉上获得我想要实现的目标。
单元格代码:
- (void) updateConstraints {
if (self.postObject.timelinePostText && self.postObject.timelinePostMultimedia) {
self.imageMinusTextViewConstraint.priority = 900;
self.imagePlusTextViewConstraint.priority = 910;
self.textViewMinusImageViewConstraint.priority = 900;
self.textViewPlusImageViewConstraint.priority = 910;
}
else if (self.postObject.timelinePostMultimedia) {
self.imageMinusTextViewConstraint.priority = 910;
self.imagePlusTextViewConstraint.priority = 900;
}
else if (self.postObject.timelinePostText) {
self.textViewMinusImageViewConstraint.priority = 910;
self.textViewPlusImageViewConstraint.priority = 900;
}
[super updateConstraints];
}
- (void) configureCellWith: (AFTimelinePostObject*) postObject {
self.postObject = postObject;
self.userNameLabel.text = postObject.timelinePostOriginalPoster;
self.dateLabel.text = [[AFTimelinePostObject dateFormatterInternet] stringFromDate:postObject.timelinePostDateObject];
self.postTitleLabel.text = postObject.timelinePostTitle;
self.multimediaMediaType = postObject.timelinePostMultimedia ? [self checkMediaTypeAtPath: postObject.timelinePostMultimedia] : kMediaTypeUnknown;
if (postObject.timelinePostMultimedia && postObject.timelinePostText) {
[self.postImageView setImageWithURL:[NSURL URLWithString:postObject.timelinePostMultimedia] placeholderImage:nil];
self.postTextView.text = postObject.timelinePostText;
}
else if (postObject.timelinePostMultimedia) {
[self bringSubviewToFront:self.postImageView];
[self.postImageView setImageWithURL:[NSURL URLWithString:postObject.timelinePostMultimedia] placeholderImage:nil];
}
else if (postObject.timelinePostText) {
[self bringSubviewToFront:self.postTextView];
self.postTextView.text = postObject.timelinePostText;
self.postImageView.image = nil;
}
[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
[self setNeedsLayout];
[self layoutIfNeeded];
}
删除视图不是一个解决方案,因为单元格是回收的,如果需要,我应该重新添加它,但这样我想我错过了与回收相关的性能优势。
不幸的是,单元格仍然被等分为文本和图像,而不会根据传递的数据更改其帧。
我缺少什么?不要删除约束视图。相反,将您在xib/情节提要中设置的约束连接到代码中的一个出口,并在
configureCell
方法中修改其常量
值。不要玩弄优先权。根据是否存在图像或文本更改常量
如果您的逻辑只允许文本单元格或图像单元格,则可以使用不同的标识符设置两个不同的单元格并相应地出列。这将在一定程度上简化您的配置逻辑
而且,代替
[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
[self setNeedsLayout];
[self layoutIfNeeded];
只需调用
[self-setNeedsLayout]代码>好吧,我提取了一个小样本,使事情变得简单。
基本上有两个错误:
优先级不应该在updateConstraints
中更新,我仍然试图找到一个关于这种方法的海豚的非常清楚的答案,但似乎只有在添加(可能不考虑删除)约束时才应该使用
我将-bringSubViewToFront
发送到了错误的父级,正确的是-contentView
这是正确的代码,谢谢@Leo对我的支持
//- (void) updateConstraints {
// if (_postObject[TEXT_KEY] && _postObject[IMAGE_NAME_KEY]) {
// self.imageMinusTextViewConstraint.priority = 800;
// self.imagePlusTextViewConstraint.priority = 999;
// self.textViewMinusImageViewConstraint.priority = 800;
// self.textViewPlusImageViewConstraint.priority = 999;
//
// }
// else if (_postObject[IMAGE_NAME_KEY]) {
// self.imageMinusTextViewConstraint.priority = 999;
// self.imagePlusTextViewConstraint.priority = 800;
// }
// else if (_postObject[TEXT_KEY]) {
// self.textViewMinusImageViewConstraint.priority = 999;
// self.textViewPlusImageViewConstraint.priority = 800;
// }
//
// [super updateConstraints];
//}
//
//
//- (void) layoutSubviews {
// [super layoutSubviews];
//}
- (void) configureCellWith: (NSDictionary*) postObject {
//Configurare gli elmenti già presenti
self.postObject = postObject;
//Check the presence of some kind of data
if (postObject[TEXT_KEY] && postObject[IMAGE_NAME_KEY]) {
self.imageMinusTextViewConstraint.priority = 800;
self.imagePlusTextViewConstraint.priority = 999;
self.textViewMinusImageViewConstraint.priority = 800;
self.textViewPlusImageViewConstraint.priority = 999;
self.postImageView.image = [UIImage imageNamed:postObject[IMAGE_NAME_KEY]];
self.postTextView.text = postObject[TEXT_KEY];
}
else if (postObject[IMAGE_NAME_KEY]) {
self.imageMinusTextViewConstraint.priority = 999;
self.imagePlusTextViewConstraint.priority = 800;
self.postImageView.image = [UIImage imageNamed:postObject[IMAGE_NAME_KEY]];
self.postTextView.text = nil;
[self.contentView bringSubviewToFront:self.postImageView];
}
else if (postObject[TEXT_KEY]) {
self.textViewMinusImageViewConstraint.priority = 999;
self.textViewPlusImageViewConstraint.priority = 800;
self.postTextView.text = postObject[TEXT_KEY];
self.postImageView.image = nil;
[self.contentView bringSubviewToFront:self.postTextView];
}
// [self setNeedsLayout];
// [self layoutIfNeeded];
}
谢谢你的建议。实际上,生产代码使用不同的单元格来实现某种可能性。我不想更改常量,因为我认为我将错过以后仅在脚本编辑器上工作的可能性,是的,我可以在两者之间交换常量值。这里的要点是,我想做的是可能的,我非常确定,但我不明白为什么不起作用,或者至少我想确定这是不可能的。@Andrea在我看来,你仍然看到文本视图和图像视图的原因是因为约束之间没有“斗争”,所以它没有优先权,因为按原样,单元满足布局约束。