如何调整包含 UITextView 的 UICollectionViewListCell 的大小?

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

这是一个简单的集合视图,具有组合布局和可比较的数据源。

它显示一个类型为

UICollectionViewListCell
的单元格,其
contentView
有一个文本视图作为子视图。

import UIKit

class ViewController: UIViewController {
    var collectionView: UICollectionView!
    let textView = UITextView()
    
    var dataSource: UICollectionViewDiffableDataSource<Section, Int>!
    
    enum Section: CaseIterable {
        case first
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        configureHierarchy()
        configureDataSource()
    }
    
    private func configureHierarchy() {
        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())
        view.addSubview(collectionView)
        collectionView.autoresizingMask = [.flexibleHeight, .flexibleWidth]

        textView.delegate = self
    }
    
    func configureDataSource() {
        let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { [weak self] cell, indexPath, itemIdentifier in
            guard let self else { return }
            
            cell.contentView.addSubview(textView)
            textView.pinToSuperviewMargins()
        }
        
        dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
            collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier)
        }
        
        var snapshot = NSDiffableDataSourceSnapshot<Section, Int>()
        snapshot.appendSections(Section.allCases)
        snapshot.appendItems([1], toSection: .first)
        dataSource.apply(snapshot)
    }
    
    func createLayout() -> UICollectionViewLayout {
        UICollectionViewCompositionalLayout { section, layoutEnvironment in
            var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
            return NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment)
        }
    }
}
extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        // Do something here?
    }
}

pinToSuperviewMargins 方法将调用它的视图的顶部、底部、前导和尾随约束设置为其超级视图,并将其translatesAutoResizingMaskIntoConstraints 属性设置为 false:

extension UIView {
    func pinToSuperviewMargins(
        top: CGFloat = 0,
        bottom: CGFloat = 0,
        leading: CGFloat = 0,
        trailing: CGFloat = 0,
        file: StaticString = #file,
        line: UInt = #line
    ) {
        guard let superview = self.superview else {
            let localFilePath = URL(fileURLWithPath: "\(file)").lastPathComponent
            print(">> \(#function) failed in file: \(localFilePath), at line: \(line): could not find \(Self.self).superView.")
            return
        }
        
        self.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            self.topAnchor.constraint(equalTo: superview.topAnchor, constant: top),
            self.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: bottom),
            self.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: leading),
            self.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: trailing),
        ])
    }
    
    func pinToSuperviewMargins(constant c: CGFloat = 0, file: StaticString = #file, line: UInt = #line) {
        self.pinToSuperviewMargins(top: c, bottom: c, leading: c, trailing: c, file: file, line: line)
    }
}

我尝试在

collectionView.setNeedsLayout()
中拨打
textViewDidChange(_:)
但不起作用。

在处理表格视图时,我曾经使用

tableView.beginUpdates(); tableView.endUpdates()
来完成单元格大小调整。

我在另一篇文章中读到有人问“为什么要把文本视图放在集合视图单元格中?”,并且在我的许多问题下都出现了类似的问题,所以让我提前问你不要问任何与问题无关的内容,直到得到解答为止。

uikit
1个回答
0
投票

为了让

UITextView
“自动调整”其高度,我们必须禁用滚动:

    textView.isScrollEnabled = false
    cell.contentView.addSubview(textView)

然后,在您的

textViewDidChange()
处理程序中,告诉集合视图需要重新布局其单元格:

func textViewDidChange(_ textView: UITextView) {
    // Do something here?
    collectionView.collectionViewLayout.invalidateLayout()
}
© www.soinside.com 2019 - 2024. All rights reserved.