ios - таблица - uitableviewcell swift




Создание UITableView программно в Swift (4)

Я пытаюсь реализовать UITableView программно без использования xib или Storyboards. Это мой код:

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let table: UITableViewController = MyTableViewController()
        let tableView: UITableView = UITableView()
        tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
        tableView.dataSource = table
        tableView.delegate = table

        self.view.addSubview(tableView)
    }
}

MyTableViewController.swift

import UIKit

class MyTableViewController: UITableViewController {

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        NSLog("sections")
        return 2
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        NSLog("rows")
        return 3
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        NSLog("get cell")
        let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
        cell.textLabel!.text = "foo"
        return cell
    }  
}

Но когда я запускаю приложение, все, что я получаю, это пустая таблица. В журнале я вижу несколько строк sections и rows , но не get cell . Как я могу исправить этот код, чтобы получить таблицу с 6 строками текста foo ?


Вам не нужно создавать отдельный класс для UITableView. Только в вашем классе ViewController реализуют протоколы UITableViewDelegate и UITableViewDataSource, а затем реализуют методы делегирования. Я думаю, что ваш код должен быть похож

class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {

    override func viewDidLoad() {
        super.viewDidLoad()

        let table: UITableViewController = MyTableViewController()
        let tableView: UITableView = UITableView()
        tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
        tableView.dataSource = table
        tableView.delegate = table

        self.view.addSubview(tableView)
    }
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        NSLog("sections")
        return 2
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        NSLog("rows")
        return 3
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        NSLog("get cell")
        let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
        cell.textLabel!.text = "foo"
        return cell
    } 
}

Расскажите нам больше информации или покажите журналы, если вы все еще сталкиваетесь с проблемой.


Нет никакого смысла, что вы используете UITableViewController в качестве источника данных и делегируете его для представления табличного представления вашего контроллера. Ваш собственный контроллер представления должен быть источником данных и делегатом таблицы.

Поскольку вам, похоже, нужен контроллер вида с табличным представлением, который не занимает весь вид, переместите все на свой контроллер представления следующим образом:

ViewController.swift:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let tableView: UITableView = UITableView()
        tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
        tableView.dataSource = self
        tableView.delegate = self

        self.view.addSubview(tableView)
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        NSLog("sections")
        return 2
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        NSLog("rows")
        return 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        NSLog("get cell")
        let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
        cell.textLabel!.text = "foo"
        return cell
    }  
}

У меня была аналогичная проблема в том, что данные не будут заполняться для моего программного UITableView. Это связано с тем, что я использовал делегат / источник данных без сильной ссылки. Как только я сохранил ссылку на него (у меня был один класс, реализующий как UITableViewDataSource, так и UITableViewDelegate), данные были заполнены.


Обновлено для Swift 3

Опция 1:

import UIKit
//
// MARK :- TableViewController
//
class TableViewController: UITableViewController {

    private let headerId = "headerId"
    private let footerId = "footerId"
    private let cellId = "cellId"

    //
    // MARK :- HEADER
    //
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

        return 150
    }

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! CustomTableViewHeader
        return header
    }

    //
    // MARK :- FOOTER
    //
    override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {

        return 150
    }

    override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {

        let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerId) as! CustomTableViewFooter
        return footer
    }

    //
    // MARK :- CELL
    //
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return 1
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return 150
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CustomTableCell
        return cell
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        title = "TableView Demo"
        view.backgroundColor = .white
        setupTableView()
    }

    func setupTableView() {

        tableView.backgroundColor = .lightGray
        tableView.register(CustomTableViewHeader.self, forHeaderFooterViewReuseIdentifier: headerId)
        tableView.register(CustomTableViewFooter.self, forHeaderFooterViewReuseIdentifier: footerId)
        tableView.register(CustomTableCell.self, forCellReuseIdentifier: cellId)
    }
}

//
// MARK :- HEADER
//
class CustomTableViewHeader: UITableViewHeaderFooterView {

    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)

        contentView.backgroundColor = .orange
    }

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

//
// MARK :- FOOTER
//
class CustomTableViewFooter: UITableViewHeaderFooterView {

    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)

        contentView.backgroundColor = .green
    }

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

//
// MARK :- CELL
//
class CustomTableCell: UITableViewCell {

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        contentView.backgroundColor = .white
    }

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

Вариант 2: заменить выше Вариант 1 TableViewController с этим классом

import UIKit
//
// MARK :- ViewController
//
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    private let headerId = "headerId"
    private let footerId = "footerId"
    private let cellId = "cellId"

    lazy var tableView: UITableView = {

        let tv = UITableView(frame: .zero, style: .plain)
        tv.translatesAutoresizingMaskIntoConstraints = false
        tv.backgroundColor = .lightGray
        tv.delegate = self
        tv.dataSource = self
        tv.register(CustomTableViewHeader.self, forHeaderFooterViewReuseIdentifier: self.headerId)
        tv.register(CustomTableViewFooter.self, forHeaderFooterViewReuseIdentifier: self.footerId)
        tv.register(CustomTableCell.self, forCellReuseIdentifier: self.cellId)
        return tv
    }()

    //
    // MARK :- HEADER
    //
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

        return 150
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! CustomTableViewHeader
        return header
    }

    //
    // MARK :- FOOTER
    //
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {

        return 150
    }

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {

        let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerId) as! CustomTableViewFooter
        return footer
    }

    //
    // MARK :- CELL
    //
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return 1
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return 150
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CustomTableCell
        return cell
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        title = "TableView Demo"
        view.backgroundColor = .white
        view.addSubview(tableView)
        setupAutoLayout()
    }

    func setupAutoLayout() {

        tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
}







uitableview