Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 具有自动布局的UITableViewCell子类如何在运行时更改约束优先级_Ios_Uitableview_Autolayout - Fatal编程技术网

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在我看来,你仍然看到文本视图和图像视图的原因是因为约束之间没有“斗争”,所以它没有优先权,因为按原样,单元满足布局约束。