如何在UITableView内部的UITableView内部实现UITextView [英] How to Implement UITextView inside UITableView inside UITableView Swift

查看:33
本文介绍了如何在UITableView内部的UITableView内部实现UITextView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在UITableView内的UITableView内实现UITextView?

how to implement UITextView inside UITableView inside UITableView ??

(1)如果在"UITextView"中键入文本,则"UITableViewCell2"的高度会自动增加.

(1) If you type text in 'UITextView', the height of 'UITableViewCell2' is automatically increased.

(2)当"UITableViewCell2"的高度增加时,"UITableViewCell2"的高度也会相应地自动增加.

(2) When the height of 'UITableViewCell2' is increased, the height of 'UITableViewCell' is automatically increased accordingly.

我已经实现了(1)的情况,但没有实现(2)的情况.

I have implemented the case of (1) but not (2).

我应该如何实施?

推荐答案

您可能想尝试一下...

You might want to give this a try...

它使用单节表格视图.每个单元格都包含一个 UIStackView ,用于排列(变量) UITextView .

It using a single-section table view. Each cell contains a UIStackView that arranges the (variable) UITextViews.

没有 @IBOutlet @IBAction 原型单元格连接...只需分配标准的 UIViewController 自定义 TableTextViewsViewController 的类:

No @IBOutlet or @IBAction or prototype cell connections... just assign a standard UIViewController custom class to TableTextViewsViewController:

//
//  TableTextViewsViewController.swift
//  Created by Don Mag on 3/10/20.
//

import UIKit

class TextViewsCell: UITableViewCell, UITextViewDelegate {

    let frameView: UIView = {
        let v = UIView()
        v.backgroundColor = .clear

        v.layer.borderColor = UIColor(red: 0.0, green: 0.5, blue: 0.0, alpha: 1.0).cgColor
        v.layer.borderWidth = 1

        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let stackView: UIStackView = {
        let v = UIStackView()
        v.axis = .vertical
        v.spacing = 8
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let stackViewPadding: CGFloat = 8.0

    var textViewCosure: ((Int, String)->())?

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    func commonInit() -> Void {

        let g = contentView.layoutMarginsGuide

        contentView.addSubview(frameView)
        frameView.addSubview(stackView)

        // bottom constraint needs to be less than 1000 (required) to avoid auot-layout warnings
        let frameViewBottomConstrait = frameView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0)
        frameViewBottomConstrait.priority = UILayoutPriority(rawValue: 999)

        NSLayoutConstraint.activate([

            frameView.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
            frameView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
            frameView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
            frameViewBottomConstrait,

            stackView.topAnchor.constraint(equalTo: frameView.topAnchor, constant: stackViewPadding),
            stackView.leadingAnchor.constraint(equalTo: frameView.leadingAnchor, constant: stackViewPadding),
            stackView.trailingAnchor.constraint(equalTo: frameView.trailingAnchor, constant: -stackViewPadding),
            stackView.bottomAnchor.constraint(equalTo: frameView.bottomAnchor, constant: -stackViewPadding),

        ])

    }

    override func prepareForReuse() {
        super.prepareForReuse()
        stackView.arrangedSubviews.forEach {
            $0.removeFromSuperview()
        }
    }

    func fillData(_ strings: [String]) -> Void {
        strings.forEach {
            let v = UITextView()

            v.font = UIFont.systemFont(ofSize: 16.0)
            v.isScrollEnabled = false

            // hugging and compression resistance set to required for cell expansion animation
            v.setContentHuggingPriority(.required, for: .vertical)
            v.setContentCompressionResistancePriority(.required, for: .vertical)

            v.text = $0

            // frame the text view
            v.layer.borderColor = UIColor.blue.cgColor
            v.layer.borderWidth = 1

            v.delegate = self
            stackView.addArrangedSubview(v)
        }
    }

    func textViewDidChange(_ textView: UITextView) {
        guard let idx = stackView.arrangedSubviews.firstIndex(of: textView) else {
            fatalError("Shouldn't happen, but couldn't find the textView index")
        }
        textViewCosure?(idx, textView.text)
    }

}

class TableTextViewsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    let topLabel: UILabel = {
        let v = UILabel()
        v.text = "Top Label"
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let tableView: UITableView = {
        let v = UITableView()

        v.layer.borderColor = UIColor.red.cgColor
        v.layer.borderWidth = 1

        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    var myData: [[String]] = [[String]]()
    var textViewsInRows: [Int] = [
        3, 4, 2, 6, 1, 4, 3,
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        // generate some dummy data
        var i = 1
        textViewsInRows.forEach {
            var s: [String] = [String]()
            for j in 1...$0 {
                s.append("Table Row: \(i) TextView \(j)")
            }
            myData.append(s)
            i += 1
        }

        view.addSubview(topLabel)
        view.addSubview(tableView)

        let g = view.safeAreaLayoutGuide

        NSLayoutConstraint.activate([

            topLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 8.0),
            topLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
            topLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),

            tableView.topAnchor.constraint(equalTo: topLabel.bottomAnchor, constant: 8.0),
            tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
            tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
            tableView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -8.0),

        ])

        tableView.dataSource = self
        tableView.delegate = self

        tableView.separatorStyle = .none
        tableView.keyboardDismissMode = .onDrag

        tableView.register(TextViewsCell.self, forCellReuseIdentifier: "TextViewsCell")

    }

    // MARK: - Table view data source

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myData.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TextViewsCell", for: indexPath) as! TextViewsCell

        cell.fillData(myData[indexPath.row])

        cell.textViewCosure = { [weak self] idx, str in
            // update our data
            self?.myData[indexPath.row][idx] = str
            // update table view cell height
            self?.tableView.beginUpdates()
            self?.tableView.endUpdates()
        }

        return cell
    }

}

结果-红色边框是tableView,绿色边框是每个单元格的contentView,蓝色边框是每个textView:

Result - red border is the tableView, green border is each cell's contentView, blue border is each textView:

这篇关于如何在UITableView内部的UITableView内部实现UITextView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆