使用UICollectionViewFlowLayoutAutomaticSize的iOS 10/11 UICollectionViewFlowLayout导致页脚补充视图未对齐 [英] iOS 10/11 UICollectionViewFlowLayout using UICollectionViewFlowLayoutAutomaticSize results in footer supplementary view misaligned

查看:2425
本文介绍了使用UICollectionViewFlowLayoutAutomaticSize的iOS 10/11 UICollectionViewFlowLayout导致页脚补充视图未对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以这是一个有趣的问题,我们在iOS 10上找到了 UICollectionViewFlowLayout (仍然是11的问题)并使用 UICollectionViewFlowLayoutAutomaticSize for estimateItemSize。

So this is an interesting issue we found with UICollectionViewFlowLayout on iOS 10 (still an issue on 11) and using UICollectionViewFlowLayoutAutomaticSize for the estimatedItemSize.

我们发现在页脚补充视图中使用 UICollectionViewFlowLayoutAutomaticSize 获取estimatedItemSize结果漂浮在底部几个单元格之上。(红色/粉红色是标题,绿色是页脚。)

We've found that using UICollectionViewFlowLayoutAutomaticSize for the estimatedItemSize results in the footer supplementary view floating above the bottom few cells.(Red/Pink is the header, Green is the footer.)


< a href =https://i.stack.imgur.com/0fAt7.png =noreferrer>

以下是示例应用的VC代码:

import UIKit

class ViewController: UIViewController {

    // MARK: Properties

    let texts: [String] = [
        "This is some text",
        "This is some more text",
        "This is even more text"
    ]

    // MARK: Outlets

    @IBOutlet var collectionView: UICollectionView! {
        didSet {
            self.collectionView.backgroundColor = .orange
        }
    }

    // MARK: Lifecycle

    override func viewDidLoad() {

        super.viewDidLoad()

        // Layout
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        if #available(iOS 10.0, *) {
            layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
        } else {
            layout.estimatedItemSize = CGSize(width: self.collectionView.bounds.width, height: 50)
        }
        self.collectionView.collectionViewLayout = layout

        // Register Cells
        self.collectionView.register(UINib(nibName: "TextCell", bundle: nil), forCellWithReuseIdentifier: String(describing: TextCell.self))
        self.collectionView.register(UINib(nibName: "SectionHeader", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: String(describing: SectionHeader.self))
        self.collectionView.register(UINib(nibName: "SectionFooter", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: String(describing: SectionFooter.self))

        self.collectionView.reloadData()
    }
}

// MARK: - UICollectionViewDelegateFlowLayout Methods

extension ViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

        return CGSize(width: self.collectionView.bounds.width, height: 90)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {

        return CGSize(width: self.collectionView.bounds.width, height: 90)
    }
}

// MARK: - UICollectionViewDataSource Methods

extension ViewController: UICollectionViewDataSource {

    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        return self.texts.count
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: TextCell.self), for: indexPath)

        if let textCell = cell as? TextCell {

            let text = self.texts[indexPath.row]
            textCell.configure(text: text)
        }

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        switch kind {
        case UICollectionElementKindSectionHeader:

            return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: SectionHeader.self), for: indexPath)

        case UICollectionElementKindSectionFooter:

            return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: SectionFooter.self), for: indexPath)

        default:
            return UICollectionReusableView()
        }
    }
}

// MARK: - UICollectionViewDelegate Methods

extension ViewController: UICollectionViewDelegate {

}

有没有人设法获得UICollectionViewFlowLayoutAutomaticSize在具有补充页眉和页脚视图的iOS 10上工作?如果我在estimatedItemSize中添加一个大小,那么它似乎可以工作,但我想知道使用新的iOS 10功能是否存在错误,或者我是否使用错误。

Has anyone managed to get UICollectionViewFlowLayoutAutomaticSize to work on iOS 10 with supplementary header and footer views? If I add a size to the estimatedItemSize then it appears to work, but I want to know if there is a bug in using the new iOS 10 feature or if I'm using it incorrectly.

向Apple提交的错误ID为: 28843116

The bug filed with Apple has the ID: 28843116

更新:这仍然显示为是10.3 Beta 1的问题

UPDATE: This still appears to be an issue on 10.3 Beta 1

更新2 :这仍然是iOS 11 Beta 1中的一个问题

UPDATE 2: This still appears to be an issue in iOS 11 Beta 1

推荐答案

UICollectionViewFlowLayout 支持细胞的自动布局,它不支持补充意见。每次自动布局代码更新单元格的框架时,它都不会对页眉和页脚做任何处理。因此,您需要告诉布局它应该使页眉和页脚无效。并且有一种方法可以做到这一点!

UICollectionViewFlowLayout supports auto layout for cells very well, BUT it does not supports it for supplementary views. Each time when auto layout code updates cell's frame it does nothing with headers and footers. So you need to tell layout that it should invalidate headers and footers. And there is a method for this!

你应该覆盖 UICollectionViewLayout func invalidationContext(forPreferredLayoutAttributes:UICollectionViewLayoutAttributes,withOriginalAttributes:UICollectionViewLayoutAttributes )并在其中执行补充视图无效。

You should override UICollectionViewLayout's func invalidationContext(forPreferredLayoutAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes: UICollectionViewLayoutAttributes) and perform supplementary view invalidation in it.

示例:

override open func invalidationContext(forPreferredLayoutAttributes preferred: UICollectionViewLayoutAttributes,
        withOriginalAttributes original: UICollectionViewLayoutAttributes)
                -> UICollectionViewLayoutInvalidationContext {
    let context: UICollectionViewLayoutInvalidationContext = super.invalidationContext(
            forPreferredLayoutAttributes: preferred,
            withOriginalAttributes: original
    )

    let indexPath = preferred.indexPath

    if indexPath.item == 0 {
        context.invalidateSupplementaryElements(ofKind: UICollectionElementKindSectionHeader, at: [indexPath])
    }

    return context
}

在上面的示例中,我使用 UICollectionViewFlowLayout <提供的失效上下文/ code>如果节中的第一个单元格无效,则使标题补充视图无效。您也可以将此方法用于页脚失效。

In example above I am using invalidation context provided by UICollectionViewFlowLayout to invalidate header supplementary view if first cell in section was invalidated. You can use this method for footer invalidation as well.

这篇关于使用UICollectionViewFlowLayoutAutomaticSize的iOS 10/11 UICollectionViewFlowLayout导致页脚补充视图未对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆