【问题标题】:UICollectionViewFlowLayout estimatedItemSize does not work properly with iOS12 though it works fine with iOS 11.*UICollectionViewFlowLayoutestimatedItemSize 不能在 iOS12 上正常工作,尽管它在 iOS 11 上工作正常。*
【发布时间】:2019-01-14 01:43:42
【问题描述】:

对于我们使用的 UICollectionView 的动态高度单元格,

if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout {
    layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}

通过适当的高度和宽度限制,它可以在 iOS 11.* 版本中正常工作,但它会破坏并且不会使单元格在 iOS 12.0 中动态化

【问题讨论】:

  • 可能相关:In iOS 12, when does the UICollectionView layout cells, use autolayout in nib。特别是,我对 AutoLayoutCollectionView 的回答可能会有所帮助。
  • 我发现:在 iOS 12 中,estimatedItemSize 被编译并添加为大小约束。它与其他指定的约束冲突。 ale84 的解决方案对我有用,但控制台上也出现了冲突约束。我个人对 collection view 的体验是,每个 OS 版本都存在一些 bug,非常烦人。

标签: swift uicollectionview uicollectionviewlayout ios12 uicollectionviewflowlayout


【解决方案1】:

我也有同样的问题。使用 UILabels 来调整 collectionview 的大小。如果我在重新加载数据之前运行collectionView.collectionViewLayout.invalidateLayout(),它可以很好地调整标签大小。

还是不太对。我很难想象,因为我是在模拟器和设备上运行它。

【讨论】:

    【解决方案2】:

    就我而言,我通过向单元格的 contentView 显式添加以下约束来解决此问题。

    class Cell: UICollectionViewCell {
        // ...
    
        override func awakeFromNib() {
            super.awakeFromNib()
    
            // Addresses a separate issue and prevent auto layout warnings due to the temporary width constraint in the xib.
            contentView.translatesAutoresizingMaskIntoConstraints = false
    
            // Code below is needed to make the self-sizing cell work when building for iOS 12 from Xcode 10.0:
            let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
            let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
            let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
            let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
            NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
        }
    }
    

    这些约束已经存在于单元格的 xib 中,但不知何故,它们对于 iOS 12 来说还不够。

    建议在各个地方调用collectionView.collectionViewLayout.invalidateLayout() 的其他线程对我的情况没有帮助。

    此处的示例代码:https://github.com/larrylegend/CollectionViewAutoSizingTest

    这会将解决方法应用于https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2 的教程中的代码:

    【讨论】:

    • 谢谢,有同样的问题,这对我有用。而且我只为 iOS12 调用此代码: if #available(iOS 12.0, *) { }
    • 它工作正常。谢谢你,你拯救了我的日子。
    • 你是怎么想出来的?我不认为苹果在任何地方都提到了这个巨大的突破性变化。很遗憾,他们让我们用这样的样板垃圾污染了我们的应用程序代码。
    • @AndrewKoster 直觉和幸运猜测。我认为这段代码只是一种解决方法,Apple 应该解决这个问题。
    • @RajanMaharjan 您好,从您的示例来看,我认为您应该将布局的itemSize 设置为UICollectionViewFlowLayout.automaticSize,并将estimatedItemSize 设置为估计值。
    【解决方案3】:

    我设法通过将此类代码放入我的 UICollectionViewCell 子类来解决这个问题

    - (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
        [self updateConstraintsIfNeeded];
        CGSize size = [self systemLayoutSizeFittingSize:CGSizeMake(1000, 1000)];
    
        CGRect alteredRect = layoutAttributes.frame;
        alteredRect.size = size;
        layoutAttributes.frame = alteredRect;
        return layoutAttributes;
    }
    

    像这样子类化 UICollectionView

    @interface CustomCollectionView ()
    @property (nonatomic) BOOL shouldInvalidateLayout;
    @end
    
    @implementation CustomCollectionView
    
    - (void)layoutSubviews {
        [super layoutSubviews];
        if (self.shouldInvalidateLayout) {
            [self.collectionViewLayout invalidateLayout];
            self.shouldInvalidateLayout = NO;
        }
    }
    
    - (void)reloadData {
        self.shouldInvalidateLayout = YES;
        [super reloadData];
    }
    
    @end
    

    【讨论】:

      【解决方案4】:

      根据ale84 的回答,由于我需要在多个地方修复 iOS 12,我创建了一个 UICollectionViewCell 扩展,我将其命名为 UICollectionViewCell+iOS12:

      extension UICollectionViewCell {
          /// This is a workaround method for self sizing collection view cells which stopped working for iOS 12
          func setupSelfSizingForiOS12(contentView: UIView) {
              contentView.translatesAutoresizingMaskIntoConstraints = false
              let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
              let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
              let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
              let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
              NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
          }
      }
      

      然后在您的集合视图单元格中,我们执行以下操作(如果您的单元格是在 IB 中创建的):

      override func awakeFromNib() {
          super.awakeFromNib()
          if #available(iOS 12, *) { setupSelfSizingForiOS12(contentView: contentView) }
      }
      

      【讨论】:

      • UICollectionViewCell 具有属性contentView。无需将其作为参数传递。
      【解决方案5】:

      上述答案的Objective C版本:

      -(void)awakeFromNib{
          [super awakeFromNib];
      
          if (@available(iOS 12.0, *)) {
              // Addresses a separate issue and prevent auto layout warnings due to the temporary width constraint in the xib.
              self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
      
              // Code below is needed to make the self-sizing cell work when building for iOS 12 from Xcode 10.0:
      
              NSLayoutConstraint *leftConstraint = [self.contentView.leftAnchor constraintEqualToAnchor:self.leftAnchor constant:0];
              NSLayoutConstraint *rightConstraint = [self.contentView.rightAnchor constraintEqualToAnchor:self.rightAnchor constant:0];
              NSLayoutConstraint *topConstraint = [self.contentView.topAnchor constraintEqualToAnchor:self.topAnchor constant:0];
              NSLayoutConstraint *bottomConstraint = [self.contentView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:0];
      
              [NSLayoutConstraint activateConstraints:@[leftConstraint, rightConstraint, topConstraint, bottomConstraint]];
          }
      
      }
      

      对于像我这样的 Objective-C 爱好者 ;) 干杯!!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-18
        相关资源
        最近更新 更多