如何向 UITableViewController 添加粘性页脚?

Posted

技术标签:

【中文标题】如何向 UITableViewController 添加粘性页脚?【英文标题】:How can I add a sticky footer to UITableViewController? 【发布时间】:2020-05-15 19:19:15 【问题描述】:

我正在 Swift Playgrounds for iPad 中编写一个模拟消息应用程序。到目前为止,我有一个带有自定义单元格的UITableViewController,其背景颜色每隔一个单元格都会改变。现在,我想在屏幕底部添加一个粘性页脚,其中包含一个文本字段和一个发送按钮,以便用户可以发送消息。我不太确定如何解决这个问题。有任何想法吗?这是我目前所拥有的:

import UIKit
import PlaygroundSupport

class ViewController: UITableViewController 

    let textMessages = [
        "Here's my very first message",
        "I'm going to message another long message that will word wrap",
        "I'm going to message another long message that will word wrap, I'm going to message another long message that will word wrap, I'm going to message another long message that will word wrap",
        "Somejfjfidiskkejejsjsjsjdjjdj blah blah blah"
    ]

    override func viewDidLoad() 
        super.viewDidLoad()

        navigationItem.title = "Messages"
        navigationController?.navigationBar.prefersLargeTitles = true

        tableView.register(ChatMessageCell.self, forCellReuseIdentifier: "cell_1")
        tableView.separatorStyle = .none
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return textMessages.count
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell_1", for: indexPath) as! ChatMessageCell
        cell.selectionStyle = .none

        if indexPath.row % 2 == 1
            cell.messageLabel.text = textMessages[indexPath.row]
            //cell.setupConstraints(side: 1)
            cell.bubbleBackgroundView.backgroundColor = UIColor(white: 0.9, alpha: 1)
            return cell
        else
            cell.messageLabel.text = textMessages[indexPath.row]
            //cell.setupConstraints(side: 0)
            cell.bubbleBackgroundView.backgroundColor = .blue
            return cell
        
    
    //let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! ChatMessageCell
    //        cell.textLabel?.text = "We want to provide a longer string that is actually going to wrap onto the next line and maybe even a third line."
    //        cell.textLabel?.numberOfLines = 0


class ChatMessageCell: UITableViewCell 

    let messageLabel = UILabel()
    let bubbleBackgroundView = UIView()
    var leadingAnchorConstant = CGFloat()

    func setupConstraints(side: Int)
        if side == 1
            leadingAnchorConstant = frame.size.width - 176
        else
            leadingAnchorConstant = 32
        
    

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

        bubbleBackgroundView.backgroundColor = .yellow
        let gradient = CAGradientLayer()

        bubbleBackgroundView.layer.shadowOpacity = 0.35
        bubbleBackgroundView.layer.shadowRadius = 6
        bubbleBackgroundView.layer.shadowOffset = CGSize(width: 0, height: 0)
        bubbleBackgroundView.layer.shadowColor = UIColor.black.cgColor

        bubbleBackgroundView.layer.cornerRadius = 25
        bubbleBackgroundView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(bubbleBackgroundView)

        addSubview(messageLabel)
        //        messageLabel.backgroundColor = .green
        messageLabel.text = "We want to provide a longer string that is actually going to wrap onto the next line and maybe even a third line."
        messageLabel.numberOfLines = 0

        messageLabel.translatesAutoresizingMaskIntoConstraints = false

        // lets set up some constraints for our label
        let constraints = [messageLabel.topAnchor.constraint(equalTo: topAnchor, constant: 32),
                           messageLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 32),
                           messageLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -32),
                           messageLabel.widthAnchor.constraint(equalToConstant: 250),

                           bubbleBackgroundView.topAnchor.constraint(equalTo: messageLabel.topAnchor, constant: -16),
                           bubbleBackgroundView.leadingAnchor.constraint(equalTo: messageLabel.leadingAnchor, constant: -16),
                           bubbleBackgroundView.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 16),
                           bubbleBackgroundView.trailingAnchor.constraint(equalTo: messageLabel.trailingAnchor, constant: 16),
        ]

        NSLayoutConstraint.activate(constraints)

        //        messageLabel.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    

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



PlaygroundPage.current.liveView = ViewController()

【问题讨论】:

【参考方案1】:

我认为您正在寻找这些 tableview 委托方法来设置自定义页脚:

override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? 
     //let cell = tableView.dequeueReusableCell(withIdentifier: "footer_cell") as! FooterCell
     // Set up cell
     let cell = UITableViewCell()
     cell.textLabel?.text = "Footer"
     cell.backgroundColor = .white
     return cell


override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat 
     return 40.0 // Set height of footer

您可以像在 cellForRow 中使用自定义表格视图单元格一样使用它们 - 我只是使用简单的默认单元格对其进行设置以生成工作示例 - 您还可以创建 UIView() 以返回此方法

默认情况下,它会粘在表格视图上方的屏幕底部 - 如果不是这种情况,或者您希望它粘在表格底部,如果使用情节提要,您可以在属性检查器中更改此设置:

样式 - 普通 -> 粘在 tableview 顶部的视图底部

样式 - 分组 -> 无论多高,都保持在 tableview 的底部

虽然不使用页脚的另一个选项可能更好的是在 UIViewController 上使用 UITableView - 这将为您提供空间来直接在 UITableView 下的视图控制器上添加 TextView、按钮和任何其他内容

左边是 UITableViewController - 右边是 UIViewController 和 UITableView

你想怎么玩它取决于你,但我建议第二个选项在 ViewController 上提供最大的灵活性

希望这会有所帮助!

【讨论】:

以上是关于如何向 UITableViewController 添加粘性页脚?的主要内容,如果未能解决你的问题,请参考以下文章

向 UITableViewController 添加顶部/底部视图?

如何从 UIViewController 传递变量来委托 UITableViewController

如果 UITableViewController 添加到其他 UIView,委托如何工作?

故事板:如何向原型 UITableViewCell 添加插座?

快速切换到 UITableViewController 时出现黑屏

如何将选定的 UITableViewController 值添加到以前的 UITableViewController?