How to add programmatic constraints to a UITableView?

我怕爱的太早我们不能终老 提交于 2021-02-19 03:38:24

问题


I have a class set up as follows:

class SettingsController: UITableViewController {

I would like to be able to add constraints to the UITableView so that there is equal spacing either side of the table (it is currently a full width table, so a little ugly on iPad).

I have read that I can't add constraints to a UITableViewController, and instead I must add a UIViewController to my class, add a UITableView to that, and then I should be able to add the constraints to the TableView.

I've amended the class and defined the UITableView on the next line. So here are my first two lines now:

class SettingsController: UIViewController {
  var tableView = UITableView()

Further down, I have this code to attach the TableView to the UIView:

override func viewDidLoad() {
    super.viewDidLoad()   
    self.view.addSubview(tableView)
}

The app builds successfully but when trying to access this view, the screen is blank, so I've not been able to attempt the constraints part yet (the screen does display the data correctly if I revert what I've described).

Many of my existing functions within this class reference tableView for passing in the data/setting the number of rows etc, but it seems I've not done something right... is there a piece I'm missing?


回答1:


Here is a simple example of programmatically creating and adding a table view to a "normal" view:

//
//  SettingsController.swift
//
//  Created by Don Mag on 7/25/17.
//

import UIKit

class SettingsController : UIViewController, UITableViewDelegate, UITableViewDataSource {

    let tableView : UITableView = {
        let t = UITableView()
        t.translatesAutoresizingMaskIntoConstraints = false
        return t
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        // set a background color so we can easily see the table
        self.view.backgroundColor = UIColor.blue

        // add the table view to self.view
        self.view.addSubview(tableView)

        // constrain the table view to 120-pts on the top,
        //  32-pts on left, right and bottom (just to demonstrate size/position)

        tableView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 32.0).isActive = true
        tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 120.0).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -32.0).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -32.0).isActive = true

        // set delegate and datasource
        tableView.delegate = self
        tableView.dataSource = self

        // register a defalut cell
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    }

    // Note: because this is NOT a subclassed UITableViewController, 
    // DataSource and Delegate functions are NOT overridden

    // MARK: - Table view data source

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

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

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

        cell.textLabel?.text = "\(indexPath)"

        return cell
    }

    // MARK: - Table view delegate

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // etc
    }

}

You should be able to run this without edits, and get a result along these lines: It is a very simple example, so should be pretty easy to see what's going on.

If you already have your (I'm assuming, complex) Settings UITableViewController class working, it should be pretty straight-forward to follow this skeleton and convert yours to a UIViewController + UITableView-as-subview.

Alternatively, you can load your existing UITableViewController as a child view controller, and add its view (the tableview) as a subview.




回答2:


So, it looks like you need to back up a step and not try to somehow embed a a UIViewController inside a TableViewController. The recommendation you mentioned means that your SettingsController should subclass UIViewController and you should add a UITableView to that.

Adding constraints to a UITableView will treat you much nicer than trying to play with a UITableViewController at all.

Edit

You should be able to implement the constraints before you have any data. You'll just see an empty table view, but it will still show rows. Sometimes it's easier to play with constraints if you can see what you're dealing with. When you create your tableView, you can do it with: var tableView = UITableView(frame: self.view) at least to help you get your bearings.

So after you implement the constraints you need, it looks like all you'd be missing is setting the tableView's delegate and dataSource and extending your view controller to implement those methods. Then you should have data, and you can bask in the glory of your hard work.




回答3:


I'm just showing another way to add constraints.

Here first you need to set view.translatesAutoresizingMaskIntoConstraints = false and do following

// align tableView from the left and right
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-8-[view]-8-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view": tableView]))

// align tableView from the top and bottom
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[view]-8-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view": tableView]))

It will give top, bottom, leading and trailing constraints to table view with respect to self.view (it's superview).



来源:https://stackoverflow.com/questions/45311714/how-to-add-programmatic-constraints-to-a-uitableview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!