如何将 UIImageView 作为自定义附件在 UICollectionViewListCell 中垂直居中?

问题描述 投票:0回答:1

请运行以下 UIKit 应用程序。

它使用具有组合布局(列表布局)和可比较数据源的集合视图。

它有一节一排。

该单元具有图像视图作为主要配件。 How do I center a UIImageView vertically in a UICollectionViewListCell as a custom accessory?

不幸的是,一旦我为图像视图设置图像,配件就不再居中: How do I center a UIImageView vertically in a UICollectionViewListCell as a custom accessory?

import UIKit

class ViewController: UIViewController {
    var collectionView: UICollectionView!
    
    var dataSource: UICollectionViewDiffableDataSource<String, String>!

    override func viewDidLoad() {
        super.viewDidLoad()

        configureHierarchy()
        configureDataSource()
    }

    func configureHierarchy() {
        collectionView = .init(frame: .zero, collectionViewLayout: createLayout())
        view.addSubview(collectionView)
        collectionView.frame = view.bounds
    }
    
    func createLayout() -> UICollectionViewLayout {
        UICollectionViewCompositionalLayout { section, layoutEnvironment in
            let config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
            return NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment)
        }
    }
    
    func configureDataSource() {
        let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
            let iv = UIImageView()
            iv.backgroundColor = .systemRed
//            iv.image = .init(systemName: "camera")
            iv.contentMode = .scaleAspectFit
            iv.frame.size = .init(
                width: 40,
                height: 40
            )
            
            cell.accessories = [.customView(configuration: .init(
                customView: iv,
                placement: .leading(),
                reservedLayoutWidth: .actual,
                maintainsFixedSize: true
            ))]
        }
        
        dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
            collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier)
        }
        
        var snapshot = NSDiffableDataSourceSnapshot<String, String>()
        snapshot.appendSections(["main"])
        snapshot.appendItems(["demo"])
        dataSource.apply(snapshot, animatingDifferences: false)
    }
}

这似乎是一个错误,但如果我将图像视图的大小设置为 100x100,即使没有给它提供图像,单元格也不会调整大小,这让我觉得我犯了一个错误。

uikit uicollectionviewcompositionallayout
1个回答
0
投票

发生这种情况是因为您尝试设置错误的尺寸和缩放比例。

考虑不为该图像设置任何高度或宽度,让系统自行决定

    let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
        let iv = UIImageView()
        iv.backgroundColor = .systemRed
        iv.image = .init(systemName: "camera")
        iv.contentMode = .scaleAspectFit
        
        cell.accessories = [
            .customView(
                configuration: .init(
                    customView: iv,
                    placement: .leading()
                )
            )
        ]
    }

enter image description here

    let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
        let iv = UIImageView()
        iv.backgroundColor = .systemRed
        iv.image = .init(systemName: "camera")
        iv.contentMode = .center
        iv.frame.size = .init(width: 40, height: 40)
        cell.accessories = [
            .customView(
                configuration: .init(
                    customView: iv,
                    placement: .leading(),
                    reservedLayoutWidth: .actual,
                    maintainsFixedSize: true
                )
            )
        ]
    }

enter image description here


但是,如果您需要像这样更大的图像,您可以尝试这样的操作: 红色方块在同一位置,但设置原点可以解决您的对齐问题

    let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
        let iv = UIImageView()
        iv.backgroundColor = .systemRed
        iv.image = .init(systemName: "camera")
        iv.contentMode = .scaleAspectFit

        iv.bounds.origin = .init(x: 0, y: -(cell.bounds.height/2))
        iv.heightAnchor.constraint(equalToConstant: 40).isActive = true
        iv.widthAnchor.constraint(equalToConstant: 40).isActive = true
        
        cell.accessories = [
            .customView(
                configuration: .init(
                    customView: iv,
                    placement: .leading()
                )
            )
        ]
    }

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.