Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.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 14.3上的UICollectionViewCompositionLayout错误_Ios_Swift_Uicollectionview_Uikit_Uicollectionviewcompositionallayout - Fatal编程技术网

iOS 14.3上的UICollectionViewCompositionLayout错误

iOS 14.3上的UICollectionViewCompositionLayout错误,ios,swift,uicollectionview,uikit,uicollectionviewcompositionallayout,Ios,Swift,Uicollectionview,Uikit,Uicollectionviewcompositionallayout,我在iOS 14.3上遇到了一个奇怪的布局问题,集合视图使用了UICollectionViewCompositionalLayout,在我的案例中与UICollectionViewDiffableDataSource相结合。 问题是当正交部分前面有固有高度部分时,内部\u UICollectionViewOrthogonalScrollerEmbeddedScrollView的位置错误 幸运的是,我能够很容易地重现这个问题。 考虑这个数据源: 私有变量数据源:UICollectionViewDi

我在iOS 14.3上遇到了一个奇怪的布局问题,集合视图使用了
UICollectionViewCompositionalLayout
,在我的案例中与
UICollectionViewDiffableDataSource
相结合。 问题是当正交部分前面有固有高度部分时,内部
\u UICollectionViewOrthogonalScrollerEmbeddedScrollView
的位置错误

幸运的是,我能够很容易地重现这个问题。 考虑这个数据源:

私有变量数据源:UICollectionViewDiffableDataSource!
枚举节:Int、可哈希、可大小写{
案例优先=0
案例二=1
}
为每个部分创建以下布局:

专用扩展部分{
var节:NSCollectionLayoutSection{
切换自身{
案例一:第一:
let itemSize=NSCollectionLayoutSize(宽度维度:。分数宽度(1),高度维度:。估计(50))
let item=NSCollectionLayoutItem(layoutSize:itemSize)
设groupSize=NSCollectionLayoutSize(宽度维度:。分数宽度(1),高度维度:。估计(50))
let group=NSCollectionLayoutGroup.horizontal(layoutSize:groupSize,子项:[项])
let节:NSCollectionLayoutSection=.init(组:组)
返回段
案例二:
让itemSize=NSCollectionLayoutSize(宽度维度:。分数宽度(1),高度维度:。分数高度(1))
let item=NSCollectionLayoutItem(layoutSize:itemSize)
让groupSize=NSCollectionLayoutSize(宽度维度:。绝对(200),高度维度:。绝对(200))
let group=NSCollectionLayoutGroup.horizontal(layoutSize:groupSize,子项:[项])
let节:NSCollectionLayoutSection=.init(组:组)
section.orthogonalScrollingBehavior=.continuous
section.contentInsets=.init(顶部:10,前导:10,底部:10,尾随:10)
section.interGroupSpacing=10
返回段
}
}
}
打破布局的东西是进入
.first
部分,包括
itemSize
groupSize
以及
估计的高度

您可以在iOS 14.3上看到下面的结果:乍一看布局在视觉上是正确的,但您立即意识到它被破坏了,因为内部滚动视图位于错误的位置。 这意味着水平滚动在蓝色区域发生错误

在iOS 14.2之前运行完全相同的代码可以获得正确的布局。

你对这个问题怎么看? 我是否遗漏了什么,或者可能是UIKit错误


谢谢

我们有估计高度的标题,一些带有
\u UICollectionViewOrthogonalScrollerEmbeddedScrollView
的部分由于这种回归而完全被破坏。这是一个在我们的案例中有效的解决方案

public final class CollectionView: UICollectionView {
    
    public override func layoutSubviews() {
        super.layoutSubviews()
    
        guard #available(iOS 14.3, *) else { return }
    
        subviews.forEach { subview in
            guard
                let scrollView = subview as? UIScrollView,
                let minY = scrollView.subviews.map(\.frame.origin.y).min(),
                minY > scrollView.frame.minY
            else { return }
    
            scrollView.contentInset.top = -minY
            scrollView.frame.origin.y = minY
        }
    }
}

我们有一个稍微不同的用例,其中带有滚动视图的部分也使用估计的高度,因此我修改了
softenhard
的解决方案来调整滚动视图的高度

public final class CollectionView: UICollectionView {
    override public func layoutSubviews() {
        super.layoutSubviews()

        guard #available(iOS 14.3, *) else { return }

        subviews.forEach { subview in
            guard
                let scrollView = subview as? UIScrollView,
                let minY = scrollView.subviews.map(\.frame.origin.y).min(),
                let maxHeight = scrollView.subviews.map(\.frame.height).max(),
                minY > scrollView.frame.minY || maxHeight > scrollView.frame.height
            else { return }

            scrollView.contentInset.top = -minY
            scrollView.frame.origin.y = minY
            scrollView.frame.size.height = maxHeight
        }
    }
}

对我来说,这个问题在iOS
14.3
14.4
中可以重现。现在已在iOS 14.5 beta1中修复

尝试安装最新的Xcode beta版
12.5 beta
,并使用运行iOS 14.5的模拟器对其进行测试


Xcode测试版链接:

我遇到了同样的问题,而其他答案的解决方法对我来说并不适用

所以我做了这个扩展来确定它是否是有缺陷的iOS版本:

extension UICollectionView {
    static var isIosVersionWithSizeEstimationBug: Bool {
        if #available(iOS 14.5, *) {
            return false
        }
        if #available(iOS 14.3, *) {
            return true
        }
        return false
    }
}
在这种情况下,我用这个来表示绝对高度。它可能不是每个用例的解决方法。但对我来说,这是一个稳定的解决方案:

let height: NSCollectionLayoutDimension = {
    let maxPossibleHeight: CGFloat = 280
    if UICollectionView.isIosVersionWithSizeEstimationBug {
        return .absolute(maxPossibleHeight)
    } else {
        return .estimated(maxPossibleHeight)
    }
}()
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: height)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: height)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1)
let section = NSCollectionLayoutSection(group: group)

嗨,马特,我们一周前向苹果报告了这个问题,让我们等待答案。当我得到任何更新时,我会不断更新主题。谢谢你的回答。我们遇到了完全相同的问题。当
NSCollectionLayoutDimension
estimatedHeight
设置为高于正在渲染的实际单元格的值时,似乎会发生这种情况。当您将
estimatedHeight
设置为最小大小时,它会按预期工作,因此增大比例似乎有效,但减小比例似乎会导致
UICollectionViewOrthogonalScrollerEmbeddedScrollView
位置错误。我们目前正在解决这个问题,将
estimatedHeight
包装在
if#available(iOS 14.3,*){…}else{…}
之间。正在归档一个
雷达。大家好,开发人员技术支持人员回答我们,collection view团队已经意识到该漏洞,应该在下一个iOS版本中发布修复程序。遗憾的是,他们没有向我们提供修复程序的预计发布日期。是否为此提交了雷达文件?如果是这样,我想监控一下。我确实向苹果公司提出了一个问题,但它仍然被标记为打开,还没有整理好。我刚刚检查了Xcode 12.4 RC/iOS 14.4 RC,不幸的是问题仍然存在。感谢分享,这似乎很好地解决了问题+1这一个对我们来说也很好,最初看起来像上一个,但由于问题的间歇性,它有时会导致视图发生变化。虽然它修复得更好,但我们仍然间歇性地遇到问题。请更新代码以使用可用的
guard}(iOS 14.3,*),否则{return}
而不是此代码,因为它错误的
if#available(iOS 14.3,*){return}
谢谢,@EhabSaifan。更新。