简体   繁体   中英

Place a cell at bottom of uitableview

How can i place a "cellBOTTOM" at the bottom of a UITableView? I thought of using the table view footer but this cause the situation where if there are not enough cell to fill up the entire screen, the footer would not stick to the bottom of the screen, but just right below the "cellLAST". I need the "cellBOTTOM" to be at the bottom of the screen AND bottom of the table

+--------------------+    +--------------------+    +--------------------+
|       SCREEN       |    |       SCREEN       |    |       SCREEN       |  
| +----------------+ |    | +----------------+ |    | +----------------+ |
| |     TABLE      | |    | |     TABLE      | |    | |     TABLE      | |
| | +------------+ | |    | | +------------+ | |    | | +------------+ | |
| | |  cellLAST  | | |    | | |   cell 1   | | |    | | |   cell 1   | | |
| | +------------+ | |    | | +------------+ | |    | | +------------+ | |
| |                | |    | | +------------+ | |    | | +------------+ | |
| |                | |    | | |  cellLAST  | | |    | | |   cell 2   | | |
| |                | |    | | +------------+ | |    | | +------------+ | |
| |                | |    | |                | |    | | +------------+ | |
| |                | |    | |                | |    | | |   cell 3   | | |
| |                | |    | |                | |    | | +------------+ | |
| | +------------+ | |    | | +------------+ | |    | | +------------+ | |
| | | cellBOTTOM | | |    | | | cellBOTTOM | | |    | | |   cell 4   | | |
| | +------------+ | |    | | +------------+ | |    | | +------------+ | |
| +----------------+ |    | +----------------+ |    | | +------------+ | |
+--------------------+    +--------------------+    +-+ |  cellLAST  | +-+
                                                      | +------------+ |
                                                      | +------------+ |
                                                      | | cellBOTTOM | |
                                                      | +------------+ |
                                                      +----------------+

I've taken a quick look at this over lunch. I originally though tthis could be done by overriding ScrollViewDidScroll but could not work it out that way. The answer I've come up with is to decide dynamically whether the table should display a footer view or not.

In the following code (which is rough, but should give you the idea), we test whether the table's number of rows is larger than the amount we want to have on the screen (in this case I've hardcoded this to 10). If it is, then we create a footer from the last element of the source data array and set the footer height to the same height as the other cells, with a different background colour. If not, then we use cellForItemAtIndexPath to test whether we are at the last row of the dataSource, in which case we format the cell accordingly:

import UIKit

class ViewController: UIViewController {

    var myTrackingTableViewController : TrackingTableViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let sourceData : [String] = {
            var sD : [String] = [String]()
            for count in 0..<50 {            // Use the top end of this loop to configure the number of rows in the tableview
                sD.append("Number \(count)")
            }
            return sD
        }()

        myTrackingTableViewController = TrackingTableViewController(sourceData: sourceData, numberOfRowsOnScreen: 10, style: UITableViewStyle.plain)

        self.view.addSubview(myTrackingTableViewController.tableView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

class TrackingTableViewController : UITableViewController {

    let sourceData : [String]
    var footerText : String!
    var footerInline : Bool = false

    init(sourceData: [String], numberOfRowsOnScreen: Int, style: UITableViewStyle) {
        self.sourceData = sourceData
        super.init(style: style)

        if self.sourceData.count > numberOfRowsOnScreen {
            self.footerText = sourceData.last
        }
        else
        {
            footerInline = true
        }
    }

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

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

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if footerInline {
            return sourceData.count
        }
        return sourceData.count - 1
    }

    override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        if footerText != nil {
            return self.tableView.frame.height / 10
        }
        return 0
}

    override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        if footerText != nil {
            let cell = UITableViewCell()
            cell.frame = CGRect(origin: CGPoint(x: 0, y: self.tableView.frame.height - self.tableView.rowHeight), size: CGSize(width: self.tableView.frame.width, height: self.tableView.frame.height / CGFloat(10)))
            cell.backgroundColor = UIColor.red

            let textLabel = UILabel(frame: CGRect(origin: CGPoint.zero, size: cell.frame.size))
            textLabel.text = footerText

            cell.addSubview(textLabel)

            return cell
        }
        return nil
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.tableView.frame.height / 10
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell()

        // Clean

        for subview in cell.subviews {
            subview.removeFromSuperview()
        }

        // Configure

        if indexPath.row == sourceData.count - 1 && footerInline {
            cell.backgroundColor = UIColor.red
        }
        else
        {
            cell.backgroundColor = UIColor.blue
        }

        let textLabel = UILabel(frame: CGRect(origin: CGPoint.zero, size: cell.frame.size))
        textLabel.text = sourceData[indexPath.row]

        cell.addSubview(textLabel)

        return cell
    }
}

To test this, change the range of the for... loop in viewDidLoad from 0..<5 to 0..<50. You'll see the behaviour matches what you wanted to achieve.

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM