ios - 修复了具有流式布局的 UICollectionView 中项目之间的间距

标签 ios uicollectionview

<分区>

因此,我正在尝试使用 UICollectionView 实现标签列表。我正在学习本教程:http://www.cocoanetics.com/2013/08/variable-sized-items-in-uicollectionview/

问题是 UICollectionView 中的流式布局试图将项目均匀地放置在同一行上。

enter image description here

作为开发者,我只能指定minimumInteritemSpacingForSectionAtIndex ,这实际上取决于 UICollectionView 来确定实际的项目间距。

但我真正想要实现的是这样的:

enter image description here

有什么想法吗?

最佳答案

我已将 Milo 的解决方案转换为 Swift:https://github.com/Coeur/UICollectionViewLeftAlignedLayout/

它只是 UICollectionViewFlowLayout 的子类。

import UIKit

/**
 *  Simple UICollectionViewFlowLayout that aligns the cells to the left rather than justify them
 *
 *  Based on https://stackoverflow.com/questions/13017257/how-do-you-determine-spacing-between-cells-in-uicollectionview-flowlayout
 */
open class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout {
    open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return super.layoutAttributesForElements(in: rect)?.map { $0.representedElementKind == nil ? layoutAttributesForItem(at: $0.indexPath)! : $0 }
    }

    open override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        guard let currentItemAttributes = super.layoutAttributesForItem(at: indexPath)?.copy() as? UICollectionViewLayoutAttributes,
            let collectionView = self.collectionView else {
            // should never happen
            return nil
        }

        let sectionInset = evaluatedSectionInsetForSection(at: indexPath.section)

        guard indexPath.item != 0 else {
            currentItemAttributes.leftAlignFrame(withSectionInset: sectionInset)
            return currentItemAttributes
        }

        guard let previousFrame = layoutAttributesForItem(at: IndexPath(item: indexPath.item - 1, section: indexPath.section))?.frame else {
            // should never happen
            return nil
        }

        // if the current frame, once left aligned to the left and stretched to the full collection view
        // width intersects the previous frame then they are on the same line
        guard previousFrame.intersects(CGRect(x: sectionInset.left, y: currentItemAttributes.frame.origin.y, width: collectionView.frame.width - sectionInset.left - sectionInset.right, height: currentItemAttributes.frame.size.height)) else {
            // make sure the first item on a line is left aligned
            currentItemAttributes.leftAlignFrame(withSectionInset: sectionInset)
            return currentItemAttributes
        }

        currentItemAttributes.frame.origin.x = previousFrame.origin.x + previousFrame.size.width + evaluatedMinimumInteritemSpacingForSection(at: indexPath.section)
        return currentItemAttributes
    }

    func evaluatedMinimumInteritemSpacingForSection(at section: NSInteger) -> CGFloat {
        return (collectionView?.delegate as? UICollectionViewDelegateFlowLayout)?.collectionView?(collectionView!, layout: self, minimumInteritemSpacingForSectionAt: section) ?? minimumInteritemSpacing
    }

    func evaluatedSectionInsetForSection(at index: NSInteger) -> UIEdgeInsets {
        return (collectionView?.delegate as? UICollectionViewDelegateFlowLayout)?.collectionView?(collectionView!, layout: self, insetForSectionAt: index) ?? sectionInset
    }
}

extension UICollectionViewLayoutAttributes {
    func leftAlignFrame(withSectionInset sectionInset: UIEdgeInsets) {
        frame.origin.x = sectionInset.left
    }
}

关于ios - 修复了具有流式布局的 UICollectionView 中项目之间的间距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24608568/

相关文章:

ios - 为什么新的 iOS 14 UIControl Action 语法如此糟糕?

ios - 从返回 String 或 Double 的 API 获取

ios - 为什么 collectionView 单元格的布局在应该相同时会有所不同?

ios - IOS 照片应用程序如何在一个屏幕上显示数百张照片?

IOS,在 UIScrollView 内的 UILabel 上设置手势点击

ios - 如何在Swift 3.0 中设置动态创建按钮的框架

ios - AVAudioPlayer 被 MPMusicPlayerController 中断

ios - ViewWithTag 导致 UICollectionView 出现问题

ios - didSelectItemAtIndexPath 在 Collection View Swift 中不起作用

ios - 如何跨 collectionview 添加 View ?