【问题标题】:Auto layout of custom programmatic UITableViewCell fails upon scrolling自定义编程 UITableViewCell 的自动布局在滚动时失败
【发布时间】:2012-12-01 00:38:01
【问题描述】:

我正在尝试在以编程方式实现的自定义 UITableViewCell 上使用 iOS 6 的新自动布局功能。我添加了 addConstraint 调用,它一开始可以正常工作——直到我滚动。当我滚动布局后回到单元格时,布局被丢弃。垃圾我的意思是字段之间的边距都是错误的(太大,远远超出单元格的大小)。我推测这与 dequeueReusableCellWithIdentifier 方法给我留下一个“脏”单元格有关,就像你发现自己需要重新初始化单元格内的字段一样,但我似乎无法做任何事情来哄它正确渲染再次。在返回单元格之前,我尝试调用 [self.contentView updateConstraints]。我已经尝试破坏约束并重新创建它们。它不仅不起作用,而且如果在 layoutSubviews 中尝试它,它会冻结在某种无限循环中。有什么想法吗?

这是建立约束的代码。它位于 initWithStyle:reuseIdentifier:

[self.completedLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.nextSetHeaderLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.nextSetDetailLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.youWillLearnHeaderLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.youWillLearnDetailLabel setTranslatesAutoresizingMaskIntoConstraints:NO];

[self.contentView removeConstraints:[self.contentView constraints]];

NSDictionary *views = NSDictionaryOfVariableBindings(_completedLabel, _nextSetHeaderLabel, _nextSetDetailLabel, _youWillLearnHeaderLabel, _youWillLearnDetailLabel);

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_completedLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];
[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_nextSetHeaderLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_nextSetDetailLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_youWillLearnHeaderLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_youWillLearnDetailLabel]-4-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[_completedLabel]-12-[_nextSetHeaderLabel]-0-[_nextSetDetailLabel]-12-[_youWillLearnHeaderLabel]-0-[_youWillLearnDetailLabel(>=20)]-1-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

【问题讨论】:

    标签: xcode uitableview scroll autolayout


    【解决方案1】:

    我也遇到了这个问题。如果我没有将单元格出列,那么一切似乎都正常 - 滚动、旋转等。但是,如果我将单元格出列,那么布局开始变得混乱。我可以让它工作的唯一方法是覆盖单元格的 prepareForReuse 方法。在这个方法中,

      1.删​​除所有自定义子视图
      2. 从 contentView
      中移除与这些子视图相关的所有约束 3.再次添加子视图和约束
    -(void) prepareForReuse
    {
        [self removeCustomSubviewsFromContentView];
        [self.contentView removeConstraints:self.constraints] //self.constraits holds all the added constraints
        [self setupSubviewsInContentView];
        [self addConstraintsToContentView];
    }
    

    如果有更好的方法来做到这一点,我也很想学习 :) 我相信 dequeing 的优点是 tableView 不必在内存中保存大量单元格 - 但是,使用这种方法,每次出队时都必须承担实质上设置单元的成本。

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题,如果有人有兴趣我已经找到了解决方案,请参阅question

      我做了什么:

      - (void)awakeFromNib
      {
          [super awakeFromNib];
      
          for (NSLayoutConstraint *cellConstraint in self.constraints)
          {
              [self removeConstraint:cellConstraint];
      
              id firstItem = cellConstraint.firstItem == self ? self.contentView : cellConstraint.firstItem;
              id seccondItem = cellConstraint.secondItem == self ? self.contentView : cellConstraint.secondItem;
      
              NSLayoutConstraint* contentViewConstraint = [NSLayoutConstraint constraintWithItem:firstItem
                                                                                       attribute:cellConstraint.firstAttribute
                                                                                       relatedBy:cellConstraint.relation
                                                                                          toItem:seccondItem
                                                                                       attribute:cellConstraint.secondAttribute
                                                                                      multiplier:cellConstraint.multiplier
                                                                                        constant:cellConstraint.constant];
      
              [self.contentView addConstraint:contentViewConstraint];
          }
      }
      

      【讨论】:

      • 麻烦的是原始海报要求关于以编程方式创建的 UITableViewCell 的提示,您的是通过 xib 或情节提要创建的。完全不同的动物。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多