如何从屏幕底部弹出 tableView?

Posted

技术标签:

【中文标题】如何从屏幕底部弹出 tableView?【英文标题】:how to popup tableView from bottom of screen? 【发布时间】:2020-07-30 11:12:58 【问题描述】:

在我的项目中,我希望在呈现 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"


【问题讨论】:

【参考方案1】:

问题来了

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

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

【讨论】:

为什么将 heightAnchot 常量设置为 300? 最初表是不可见的,你给它这个值使它呈现正确的 contentSize 因为 0 不会使它甚至可见它可能是 200 0r 100 但你不应该把它设为 0 最终它将是它的 contentSize 根据您当前的代码 如果我使用 UIView 而不是 UIViewController,那么我应该把这些代码放在哪里? 在将其添加为子视图后,您将不得不使用延迟,因为在 UIView 子类中没有像 viewDidAppear 这样的回调

以上是关于如何从屏幕底部弹出 tableView?的主要内容,如果未能解决你的问题,请参考以下文章

从屏幕底部弹出一个小弹出窗口使用啥 Widget Flutter

UIActionSheet 应该从弹出窗口中调用,但从主屏幕底部显示

UITableView - 最后一节的页脚滚动到屏幕底部。如何预防?

PopupWindow底部弹出

如何在 UITableView swift 3 中使用动画在底部滚动

如何修复表格视图底部的按钮?