【问题标题】:UICollectionView Top spacingUICollectionView 顶部间距
【发布时间】:2022-01-15 19:59:58
【问题描述】:

我的 Swift Xcode 项目中的 UICollectionView 有问题 我检查了所有插图和边距,我尝试了 ViewController 的:“调整滚动视图插图”和许多其他东西,但它们都没有以任何方式改变这一点。

我想减少/删除我的 collectionView 中第一行单元格上方的顶部间距

我创建了一个示例项目来查找此问题的解决方案/修复程序,但还没有任何运气

使用通过 Storyboard /Interface 构建器插入的集合视图时,这似乎是一个问题,因为如果我在代码端添加集合视图,则不会发生这种情况

这是我的视图控制器的代码:

import UIKit

struct CVData: Hashable {
    var name: String
    var value: String
}

class ViewController: UIViewController {
    
    @IBOutlet weak var myCollectionView: UICollectionView!
    var dataSource: UICollectionViewDiffableDataSource<Section, CVData>!
    var cvDataList: [CVData] = []
    enum Section {
        case main
    }
    var CVDataLabels: [String] = ["Label1:","Label2:","Label3:","Label4:","Label5:","Label6:","Label7:","Label8:"]
    var CVDataValues: [String] = []
    var snapshot: NSDiffableDataSourceSnapshot<Section, CVData>!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureCollectionView()
        buildData()
        // Do any additional setup after loading the view.
    }

    func configureCollectionView() {
        
        let layoutConfig = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
        let listLayout = UICollectionViewCompositionalLayout.list(using: layoutConfig)
        myCollectionView.collectionViewLayout = listLayout
        myCollectionView.isScrollEnabled = false
        let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, CVData> { (cell, indexPath, item) in

            var content = UIListContentConfiguration.cell()
            content.text = item.name
            content.textProperties.font.withSize(8.0)
            content.textProperties.font = UIFont.preferredFont(forTextStyle: .body)
            content.secondaryText = item.value
            content.prefersSideBySideTextAndSecondaryText = true
            content.textProperties.adjustsFontSizeToFitWidth = false
            cell.contentConfiguration = content
        }
        
        dataSource = UICollectionViewDiffableDataSource<Section, CVData>(collectionView: myCollectionView) {
            (collectionView: UICollectionView, indexPath: IndexPath, identifier: CVData) -> UICollectionViewCell? in
            
            // Dequeue reusable cell using cell registration (Reuse identifier no longer needed)
            let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration,
                                                                    for: indexPath,
                                                                    item: identifier)
            // Configure cell appearance
            cell.accessories = [.disclosureIndicator()]
            
            return cell
        
    }
    }


    func buildData() {
        
        let cvDataList = [
            CVData(name: self.CVDataLabels[0], value: "value1"),
            CVData(name: self.CVDataLabels[1], value: "value2"),
            CVData(name: self.CVDataLabels[2], value: "value3"),
            CVData(name: self.CVDataLabels[3], value: "value4"),
            CVData(name: self.CVDataLabels[4], value: "value5"),
            CVData(name: self.CVDataLabels[5], value: "value6"),
            CVData(name: self.CVDataLabels[6], value: "value6"), //added 20210510
            CVData(name: self.CVDataLabels[7], value: "value7")
        ]
        
        // Create a snapshot that define the current state of data source's data
        self.snapshot = NSDiffableDataSourceSnapshot<Section, CVData>()
        self.snapshot.appendSections([.main])
        self.snapshot.appendItems(cvDataList, toSection: .main)

        // Display data in the collection view by applying the snapshot to data source
        self.dataSource.apply(self.snapshot, animatingDifferences: false)
    }
}

这是 UICollectionView 中的尺寸检查器设置

任何帮助将不胜感激????

【问题讨论】:

  • 如果降低 CollectionView 高度(或增加每个单元格的高度)会发生什么?它可能是一个没有内容的 headerView 吗?也许您可以尝试强制为零大小? stackoverflow.com/questions/41139749/…
  • 向我们发送尺寸检查器的屏幕截图...我怀疑你那里有标题尺寸
  • 感谢您的时间 claude31 和 Fahim Parkar,因为我了解这些设置,我不希望在此处设置标题大小,因此将标题大小设置为零(参见上面添加的屏幕截图)跨度>
  • 如果我降低集合视图的高度,最后一行的单元格会被剪掉,但顶部根本不会改变:/ 你可以看到这只是一个示例项目,没有别的在它比这个collectionView...如果我减小宽度,行变得更小并且两边的间距也保持不变..就像填充在fe javascript/php/html ...但我在 Xcode 中的任何地方都找不到那些填充设置

标签: ios swift xcode uicollectionview spacing


【解决方案1】:

我没有与UICollectionViewCompositionalLayout.list 合作过,所以这只是一些快速研究和实验...

UICollectionLayoutListConfiguration 的默认 .headerMode.none ...当使用 .insetGrouped 时,我们会看到“额外空间”。

奇怪的是,还有一个 headerTopPadding 属性,我们可能希望在这里有所帮助。它的默认值为 0 ... 但似乎只有在 IS 有标题视图时才应用。

所以,如果我们设置.headerMode = .supplementary 并为标题返回一个空的UICollectionReusableView,我们可以去掉多余的空间:

现在,顶部空间与默认的左/右填充相同。

这是我用于标题视图的内容:

class EmptyHeaderView : UICollectionReusableView {
    static let reuseIdentifier:String = "emptyHeaderView"
}

对您的 configureCollectionView() 函数进行三处编辑:

func configureCollectionView() {
    
    var layoutConfig = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
    
    // 1
    // we're going to supply an "empty" header supplementary view
    layoutConfig.headerMode = .supplementary
    
    let listLayout = UICollectionViewCompositionalLayout.list(using: layoutConfig)
    
    myCollectionView.collectionViewLayout = listLayout
    myCollectionView.isScrollEnabled = false
    let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, CVData> { (cell, indexPath, item) in
        
        var content = UIListContentConfiguration.cell()
        content.text = item.name
        content.textProperties.font.withSize(8.0)
        content.textProperties.font = UIFont.preferredFont(forTextStyle: .body)
        content.secondaryText = item.value
        content.prefersSideBySideTextAndSecondaryText = true
        content.textProperties.adjustsFontSizeToFitWidth = false
        cell.contentConfiguration = content
    }
    
    dataSource = UICollectionViewDiffableDataSource<Section, CVData>(collectionView: myCollectionView) {
        (collectionView: UICollectionView, indexPath: IndexPath, identifier: CVData) -> UICollectionViewCell? in
        
        // Dequeue reusable cell using cell registration (Reuse identifier no longer needed)
        let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration,
                                                                for: indexPath,
                                                                item: identifier)
        // Configure cell appearance
        cell.accessories = [.disclosureIndicator()]
        
        return cell
        
    }
    
    // 2
    // register a reusable supplementary view for the header
    myCollectionView.register(EmptyHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: EmptyHeaderView.reuseIdentifier)

    // 3
    // provider for header suppleentary view
    dataSource.supplementaryViewProvider = { (collectionView: UICollectionView, kind: String, indexPath: IndexPath) -> UICollectionReusableView? in
        if kind == UICollectionView.elementKindSectionHeader {
            if let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: EmptyHeaderView.reuseIdentifier, for: indexPath) as? EmptyHeaderView {
                return headerView
            }
        }
        fatalError("Something's wrong with the setup...")
    }
}

【讨论】:

  • 哇,终于说得通了——很好的解释和空标题部分的很好的解决方案! ? 我应该尝试切换到 .plain 而不是 .insetGrouped,也许我自己找到了这种解决方案。我已经花了几个小时来寻找原因,我无法表达我是多么的感激,DonMag!非常感谢!谢谢!
  • @blendstylez - 很高兴它有帮助......很多时候,我对问题的看法是狭隘的,所需要的只是“一双新的眼睛”。 :)
  • 我绝对知道你的意思@DonMag,但是我应该看到或尝试过这个,但是我在 IB 中搜索,bc 我想如果它通过代码添加它必须是什么与IB:/因为我自己做这一切,没有其他人可以帮助我获得不同的角度......至少 - 吸取的教训:)谢谢! ??