微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

组合布局无法正确调整“_UICollectionViewOrthogonalScrollerEmbeddedScrollView”的高度,导致按钮无法接收事件

如何解决组合布局无法正确调整“_UICollectionViewOrthogonalScrollerEmbeddedScrollView”的高度,导致按钮无法接收事件

我在使用组合布局的集合视图时遇到问题! Card 部分应该自动调整高度的大小,它应该水平滚动,而整个集合视图垂直作为这个测试项目! 我遇到的问题是我为项目和组设置了估计高度,但是这个对象“_UICollectionViewOrthogonalScrollerEmbeddedScrollView”不会相应地调整大小,因此“_UICollectionViewOrthogonalScrollerEmbeddedScrollView”边界之外的单元格部分不接收事件 因此,如果您按下项目中最长卡片上的按钮或尝试滚动或触摸“_UICollectionViewOrthogonalScrollerEmbeddedScrollView”之外的部分,则单元格不会收到任何事件。 检查附加的屏幕截图......有没有人知道如何解决这个问题???

项目链接https://drive.google.com/file/d/1tksL0qZ1egxy7M4UD8eLMeY61H7U1ou1/view?usp=sharing

enter image description here

这是我的组合布局代码

struct CollectionViewLayout {
static func createLayout(collectionView: UICollectionView) -> UICollectionViewLayout {
    let layout = UICollectionViewCompositionalLayout { (sectionIndex,_: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
        let sectionLayoutKind = ViewController.Section.allCases[sectionIndex]
        return sectionLayout(for: sectionLayoutKind,collectionView: collectionView)
    }
    return layout
}

static func sectionLayout(for kind: ViewController.Section,collectionView: UICollectionView) -> NSCollectionLayoutSection {
    switch kind {
    case .cards:
        return cardsLayoutSection(collectionView: collectionView)
    case .buttons:
        return buttonsLayoutSection()
    }
}

static func cardsLayoutSection(collectionView: UICollectionView) -> NSCollectionLayoutSection {
    let etimationHeight: CGFloat = 300
    let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),heightDimension: .estimated(etimationHeight))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)

    let width = collectionView.frame.width - 40.0 // spacing from left and right 20 each
    let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(width),heightDimension: .estimated(etimationHeight))
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,subitem: item,count: 1)

    let section = NSCollectionLayoutSection(group: group)
    section.contentInsets = NSDirectionalEdgeInsets(top: 0,leading: 20,bottom: 0,trailing: 20)
    section.interGroupSpacing = 10
    section.orthogonalScrollingBehavior = .groupPaging
    return section
}

static func buttonsLayoutSection() -> NSCollectionLayoutSection {
    let layoutSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),heightDimension: .estimated(100))
    let item = NSCollectionLayoutItem(layoutSize: layoutSize)
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: layoutSize,count: 1)
    let section = NSCollectionLayoutSection(group: group)
    return section
}

}

这是我的单元配置器

class CellConfigurator {
let collectionView: UICollectionView

private let numberOfCards = 3

init(collectionView: UICollectionView) {
    self.collectionView = collectionView
}

var numberOfItems: Int {
    return numberOfCards
}

var activeIndex: Int {
    return 0
}

func cellForButtons(indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String.init(describing: Buttons.self),for: indexPath)
    return cell
}

func cardCell(indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String.init(describing: Card.self),for: indexPath) as! Card
    switch indexPath.row {
    case 0:
        cell.heightConstraint.constant = 300
    case 1:
        cell.heightConstraint.constant = 100
    default:
        cell.heightConstraint.constant = 500
    }
    return cell
}

}

解决方法

经过大量研究,这似乎是一个苹果错误!无论如何,我找到了一个解决方法,它子调用 collectionView 并修复“_UICollectionViewOrthogonalScrollerEmbeddedScrollView”的大小和位置。我在这篇文章中收到了这张表格 UICollectionViewCompositionalLayout bug on iOS 14.3

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
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。