如何从屏幕底部弹出tableView?

how to popup tableView from bottom of screen?

在我的项目中,我希望在显示 viewController 之后,tableView 从屏幕底部弹出,直到显示 tableView 的所有内容。 UITableViewCell 高度是动态的,我在我的项目中使用 swift 语言和 NSLayoutConstraint。我怎样才能做到这一点?它只显示了 tableView 的一部分。

这是我的代码:

class myViewController: UIViewController {

var tableView: UITableView!
var tableViewTopLayoutConstraint, tableViewHeightLayoutConstraint: NSLayoutConstraint!
private var isFirstTime: Bool = true

override func viewDidLayoutSubviews() {
    
    print("this is tableView frame Height:\(tableView.frame.height)")
    print("this is tableView content Height:\(tableView.contentSize.height)")
    
    if tableView.contentSize.height != 0 && isFirstTime {
        
        tableViewHeightLayoutConstraint.constant = tableView.contentSize.height
        showContainerView(-tableView.contentSize.height)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .gray

    tableView = UITableView()
    tableView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
    tableView.layer.cornerRadius = 20
    tableView.register(SomeUITableViewCell.self, forCellReuseIdentifier: SomeUITableViewCell.identifier)
    
    tableView.rowHeight = UITableView.automaticDimension
    
    tableView.separatorStyle = .none
    tableView.backgroundColor = .clear
    tableView.tableFooterView  = nil
    tableView.isScrollEnabled = false
    tableView.delegate = self
    tableView.dataSource = self
    tableView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(tableView)
    
    tableViewTopLayoutConstraint = tableView.topAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
    tableViewTopLayoutConstraint.isActive = true
    
    tableViewHeightLayoutConstraint = tableView.heightAnchor.constraint(equalToConstant: 0)
    tableViewHeightLayoutConstraint.isActive = true
    
    NSLayoutConstraint.activate([
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    ])
}

private func showContainerView(_ viewHeight: CGFloat) {
    
    isFirstTime = false
    tableViewTopLayoutConstraint.constant = viewHeight
    UIView.animate(withDuration: 0.5) { [weak self] in
        self?.view.layoutIfNeeded()
    }
}
}

extension myViewController: UITableViewDelegate, UITableViewDataSource {

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCell(withIdentifier: SomeUITableViewCell.identifier, for: indexPath) as! SomeUITableViewCell
    cell.setCell()
    return cell
}
}

class SomeUITableViewCell: UITableViewCell {

static let identifier = "SomeUITableViewCellId"

private var cardOrDepositNumberLabel: UILabel!
private var cardOrDepositOwnerLabel: UILabel!

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    
    selectionStyle = .none
    
    cardOrDepositNumberLabel = UILabel()
    cardOrDepositNumberLabel.numberOfLines = 0
    cardOrDepositNumberLabel.backgroundColor = .red
    cardOrDepositNumberLabel.textAlignment = .right
    cardOrDepositNumberLabel.translatesAutoresizingMaskIntoConstraints = false
    addSubview(cardOrDepositNumberLabel)
    
    NSLayoutConstraint.activate([
        cardOrDepositNumberLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
        cardOrDepositNumberLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10),
        cardOrDepositNumberLabel.topAnchor.constraint(equalTo: topAnchor),
    ])
    
    cardOrDepositOwnerLabel = UILabel()
    cardOrDepositOwnerLabel.numberOfLines = 0
    cardOrDepositOwnerLabel.textAlignment = .right
    cardOrDepositOwnerLabel.backgroundColor = .blue
    cardOrDepositOwnerLabel.translatesAutoresizingMaskIntoConstraints = false
    addSubview(cardOrDepositOwnerLabel)

    NSLayoutConstraint.activate([
        cardOrDepositOwnerLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
        cardOrDepositOwnerLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10),
        cardOrDepositOwnerLabel.topAnchor.constraint(equalTo: cardOrDepositNumberLabel.bottomAnchor),
        cardOrDepositOwnerLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
    ])
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setCell() {
    
    cardOrDepositNumberLabel.text = "some data some data some data"
    cardOrDepositOwnerLabel.text = "some data some data some data some data some data some data some data some data some data some data"
}
}

问题在这里

tableViewHeightLayoutConstraint = tableView.heightAnchor.constraint(equalToConstant: 300)

设置一个初始的非零值并在 viewDidAppear 中执行 viewDidLayoutSubviews 中的操作,最好在延迟后给 table 一些时间来计算它的实际 contentSize