【问题标题】:UITableViewCell subclass with auto layout how to change constraint priority at runtime具有自动布局的 UITableViewCell 子类如何在运行时更改约束优先级
【发布时间】:2014-04-18 15:49:32
【问题描述】:

我的故事板中有一个单元的原型。
基本上,单元格分为两部分:

  • 文本视图
  • 图像视图

单元格被初始化,其值将对象传递给单元格本身。在该方法中,单元格将其元素设置为传递的值。
主要思想是根据图像或文本的存在来更改单元格布局。为此,我过度约束了UITextViewUIImageView,一方面添加了两个具有不同优先级的约束。优先级将根据传递的对象而变化。
例如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];

}


删除视图不是解决方案,因为单元格被回收了,如果需要我应该重新添加它,但是这样我想我错过了与回收相关的性能优势。
不幸的是,单元格仍然平等地分为文本和图像,没有根据传递的数据改变它们的框架。
我错过了什么?

【问题讨论】:

    标签: ios uitableview autolayout


    【解决方案1】:

    不要删除约束视图。相反,将您在 xib/storyboard 中设置的约束连接到代码中的插座,并在您的 configureCell 方法中修改其 constant 值。不要玩弄优先级。根据是否有图像或文本更改常量。

    如果您的逻辑只允许任何一个文本单元格图像单元格,您可以设置两个具有不同标识符的不同单元格并相应地出列。这会稍微简化您的配置逻辑。

    还有,而不是

    [self setNeedsUpdateConstraints];
    [self updateConstraintsIfNeeded];
    [self setNeedsLayout];
    [self layoutIfNeeded];
    

    只需拨打[self setNeedsLayout];

    【讨论】:

    • 感谢 Leo,您的建议。实际上,生产代码使用不同的单元格来获得某种可能性。我不想更改常量,因为我认为以后我会错过仅在情节提要编辑器上工作的可能性,是的,我可以在两者之间交换常量值。这里的重点是我想做的事情是可能的,我很确定,但我不明白为什么不工作,或者至少我想确定这是不可能的。
    • @Andrea 在我看来,您仍然看到文本视图和图像视图的原因是因为约束之间没有“战斗”,所以它没有优先级,因为它是,单元格满足布局约束。
    【解决方案2】:

    好吧,我已经提取了一个小样本以使事情变得简单。 那里基本上有两个错误:

    1. 优先级不应该在updateConstraints 中更新,我仍然试图找到一个关于这种方法的海豚的非常明确的答案,但似乎你应该只在你添加(可能不考虑删除)约束时使用
    2. 我将 -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];
    
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多