这是一个简单的集合视图,具有组合布局和不同的数据源.

它显示一个类型为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方法将调用它的视图的顶部、底部、前导和尾随约束设置为其superview的,并将其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)
    }
}

我试着在textViewDidChange(_:)中调用collectionView.setNeedsLayout(),并将textView的isScrollEnabled属性设置为false,但它不起作用.

在处理表视图时,我经常通过在textViewDidChange(_:)中调用tableView.beginUpdates(); tableView.endUpdates()来完成单元格搜索.

我在另一个帖子中读到有人问"为什么你要把一个文本视图放在集合视图单元格中?",类似的问题在我的很多问题下都冒出来了,所以我先请你,在没有回答之前,不要问任何与这个问题无关的事情.

推荐答案

为了获得UITextView来"自动调整"其高度,我们必须禁用滚动:

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

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

func textViewDidChange(_ textView: UITextView) {
    // Do something here?
    collectionView.collectionViewLayout.invalidateLayout()
}

Ios相关问答推荐

Flutter应用程序无法使用IOS/Swift的蓝牙核心库发现某些外围设备

UIBezierPath包含:方法不检测到厚度大于1像素的线上的touch

设置托管在DigitalOcean上的iOS通用链接

在嵌套的DISPATCH_AFTER块中正确使用strong自/弱自

有没有办法将滚动视图RTL(阿拉伯语)与Ltr动画一起使用?

如何在后台显示 Swift UI 中的通讯通知?

将 Riverpod 从 StateNotifier 修复为 NotifierProvider 以及应用程序生命周期监控

如何在应用程序中显示我的小部件的快照?

满足条件时 SwiftUI 动画背景 colored颜色 变化

有哪些可靠的机制可以防止 CoreData CloudKit 中的数据重复?

按钮在 SwiftUI 中没有采用给定的高度和宽度

Select UITableViewCell 时 UIView backgroundColor 消失

Xcode 6 App Store 提交失败并显示您的帐户已经拥有有效的 iOS 分发证书

在 iOS 中获取设备位置(仅限国家/地区)

如何获取 UICollectionViewCell 的矩形?

没有 Mac 的 Xamarin Visual Studio IOS 开发?

AVAudioRecorder 抛出错误

UIView - 加载视图时如何获得通知?

xcode 5.1:libCordova.a 架构问题

Twitter api 文本字段值被截断