【问题标题】:cellForRowAt in TableView not updatingTableView 中的 cellForRowAt 未更新
【发布时间】:2018-07-02 20:55:14
【问题描述】:

我有一个显示购物清单名称的表格视图控制器。这些购物清单是通过购物清单类创建的,它允许我指定购物清单的名称和其中的项目。此表格视图显示大约 5 个购物清单(名称)。当我按下一个时,我转到另一个表格视图控制器,它显示了购物清单的项目。然而,当我回到购物清单(名称)表视图控制器并按下另一个购物清单时,它仍然显示旧购物清单中的项目,而不是被按下的项目。我想我已经将问题缩小到第二个表格视图控制器的 cellForItemAt 没有被再次调用。

import UIKit

class List: NSObject {

    var name: String
    var items: [String?]
    var shared: String?

    init(name: String, items: [String], shared: String?) {
        self.name = name
        self.items = items
        self.shared = shared
    }

}

enum ListType {
    case apply
    case view
}

class ListViewController: UITableViewController {

    //Initialize Variables Here
    let cellId = "cellId"

    var lists: [List] = [
        List(name: "Veggies", items: ["Fruit Loops", "Pasta"], shared: nil),
        List(name: "11/17/18", items: ["Eggs", "Green Beans", "Pirate Booty", "Bread", "Milk"], shared: nil),
        List(name: "Fruits", items: ["Fruit Loops", "Oranges"], shared: nil),
        List(name: "Red Foods", items: ["Apples", "Tomatoes", "Watermelon", "Cherries"], shared: nil),
        List(name: "Grains", items: ["Bread Crumbs", "Pasta", "Rice", "Chicken Flavored Rice"], shared: nil)
    ]

    //Create Class Lazy Vars
    lazy var newListVC: NewListViewController = {
        let launcher = NewListViewController()
        //        launcher.homeController = self
        return launcher
    }()

    lazy var listItemsVC: ListItemsViewController = {
        let launcher = ListItemsViewController()
        //        launcher.homeController = self
        return launcher
    }()

    //Setup Enums and Switches
    var listType: ListType!


    override func viewDidLoad() {
        super.viewDidLoad()

        //Things that both cases have in common:
        navigationController?.navigationBar.prefersLargeTitles = true

        let addBarButtonItem = UIBarButtonItem(title: "+", style: .plain, target: self, action: #selector(newList)) //+ Button
        addBarButtonItem.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 27)!], for: .normal)
        addBarButtonItem.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 27)!], for: .selected)

        //SWITCH STATEMENT
        switch listType as ListType {

        case ListType.apply:
            //Apply Begin
            navigationItem.title = "Apply List"

            //Setup Navigation Bar Items
            let locateBarButtonItem = UIBarButtonItem(title: "Locate Item", style: .plain, target: self, action: nil)

            //Add items to navigation bar
            navigationItem.rightBarButtonItems = [addBarButtonItem, locateBarButtonItem]
            //Apply End
        case ListType.view:
            //View Begin
            //Setup Navigation Bar
            navigationItem.title = "My Lists"

            //Add items to navigation bar
            navigationItem.rightBarButtonItem = addBarButtonItem
            navigationItem.leftBarButtonItem = editButtonItem

            //View End
        }
        //SWITCH STATEMENT END


        //Register TableView with Id: cellId
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)

    }

    @objc func newList() {
        newListVC.pageControlFunc(pageView: PageView.name)
        navigationController?.pushViewController(newListVC, animated: true) //Then pushes listVC
    }

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

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

        cell.textLabel?.text = self.lists[indexPath.row].name //Then sets cell of indexPath text = lists value of index path

        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        listItemsVC.listName = lists[indexPath.row].name
        listItemsVC.listItems = lists[indexPath.row].items
        print(listItemsVC.listItems)
        navigationController?.pushViewController(listItemsVC, animated: true)
    }

}


///////////////////////////////////////////////////////////////////////////

SECOND UITABLEVIEW - NOT UPDATING

///////////////////////////////////////////////////////////////////////////

import UIKit

class ListItemsViewController: UITableViewController {

    //Initialize Variables Here
    let cellId = "cellId1"

    var listName: String?
    var listItems: [String?] = []


    override func viewDidLoad() {
        super.viewDidLoad()

        //Things that both cases have in common:
        navigationController?.navigationBar.prefersLargeTitles = true

        //Set Title
        navigationItem.title = listName

        //Register TableView with Id: cellId
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)

        //Delegate method not called on push to view

    }

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

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

        cell.textLabel?.text = listItems[indexPath.row] //Then sets cell of indexPath text = lists value of index path

        return cell
    }

}

提前致谢!

【问题讨论】:

  • 请出示您当前的代码
  • 请参考这个解决方案。 stackoverflow.com/questions/28430663/…
  • @ahmed 感谢您的建议。对不起,我想我的问题不清楚。我可以在 viewController 之间传递数据,但我认为是当我第二次推送 viewController 时,它不会更新 cellForItemAt: indexPath,即使正在更改影响它的变量。
  • @KaylaGalway 对不起,我是新手,我该怎么做?
  • 点击编辑您的问题,然后复制并粘贴当前的表格视图代码 - 您的两个表格视图控制器中可能涉及或不涉及您的问题的任何代码

标签: ios uitableview swift4


【解决方案1】:

ViewDidLoad在 ViewController 第一次加载到内存时被调用一次。由于您的 ListsItemsViewController 是您的 ListViewController 上的一个强大属性,并且您多次导航到它,因此没有什么告诉它更新其视图或重新加载您的 tableview,因为它没有被释放(所以 ViewDidLoadTableView 委托/数据源方法不会被调用)。您也没有添加任何自定义代码告诉它更新。

如果要将这些视图控制器保留为ListViewController 的类属性,则可以在ListsItemsViewControllerViewWillAppear 方法中添加tableView.reloadData,如下所示。

import UIKit

class List: NSObject {

    var name: String
    var items: [String?]
    var shared: String?

    init(name: String, items: [String], shared: String?) {
        self.name = name
        self.items = items
        self.shared = shared
    }

}

enum ListType {
    case apply
    case view
}

class ListViewController: UITableViewController {

    //Initialize Variables Here
    let cellId = "cellId"

    var lists: [List] = [
        List(name: "Veggies", items: ["Fruit Loops", "Pasta"], shared: nil),
        List(name: "11/17/18", items: ["Eggs", "Green Beans", "Pirate Booty", "Bread", "Milk"], shared: nil),
        List(name: "Fruits", items: ["Fruit Loops", "Oranges"], shared: nil),
        List(name: "Red Foods", items: ["Apples", "Tomatoes", "Watermelon", "Cherries"], shared: nil),
        List(name: "Grains", items: ["Bread Crumbs", "Pasta", "Rice", "Chicken Flavored Rice"], shared: nil)
    ]

    //Create Class Lazy Vars
    lazy var newListVC: NewListViewController = {
        let launcher = NewListViewController()
        //        launcher.homeController = self
        return launcher
    }()

    lazy var listItemsVC: ListItemsViewController = {
        let launcher = ListItemsViewController()
        //        launcher.homeController = self
        return launcher
    }()

    //Setup Enums and Switches
    var listType: ListType!


    override func viewDidLoad() {
        super.viewDidLoad()

        //Things that both cases have in common:
        navigationController?.navigationBar.prefersLargeTitles = true

        let addBarButtonItem = UIBarButtonItem(title: "+", style: .plain, target: self, action: #selector(newList)) //+ Button
        addBarButtonItem.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 27)!], for: .normal)
        addBarButtonItem.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 27)!], for: .selected)

        //SWITCH STATEMENT
        switch listType as ListType {

        case ListType.apply:
            //Apply Begin
            navigationItem.title = "Apply List"

            //Setup Navigation Bar Items
            let locateBarButtonItem = UIBarButtonItem(title: "Locate Item", style: .plain, target: self, action: nil)

            //Add items to navigation bar
            navigationItem.rightBarButtonItems = [addBarButtonItem, locateBarButtonItem]
            //Apply End
        case ListType.view:
            //View Begin
            //Setup Navigation Bar
            navigationItem.title = "My Lists"

            //Add items to navigation bar
            navigationItem.rightBarButtonItem = addBarButtonItem
            navigationItem.leftBarButtonItem = editButtonItem

            //View End
        }
        //SWITCH STATEMENT END


        //Register TableView with Id: cellId
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)

    }

    @objc func newList() {
        newListVC.pageControlFunc(pageView: PageView.name)
        navigationController?.pushViewController(newListVC, animated: true) //Then pushes listVC
    }

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

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

        cell.textLabel?.text = self.lists[indexPath.row].name //Then sets cell of indexPath text = lists value of index path

        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        listItemsVC.listName = lists[indexPath.row].name
        listItemsVC.listItems = lists[indexPath.row].items
        print(listItemsVC.listItems)
        navigationController?.pushViewController(listItemsVC, animated: true)
    }

}


///////////////////////////////////////////////////////////////////////////

SECOND UITABLEVIEW - NOT UPDATING

///////////////////////////////////////////////////////////////////////////

import UIKit

class ListItemsViewController: UITableViewController {

    //Initialize Variables Here
    let cellId = "cellId1"

    var listName: String?
    var listItems: [String?] = []


    override func viewDidLoad() {
        super.viewDidLoad()

        //Things that both cases have in common:
        navigationController?.navigationBar.prefersLargeTitles = true

        //Set Title
        navigationItem.title = listName

        //Register TableView with Id: cellId
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)

        //Delegate method not called on push to view

    }

    //This will always get called when this view controller's view is added to the window
    //so you can guarantee it will call your delegate methods to reload the tableView with your new data
    override func viewWillAppear(animated: Bool) {
      super.viewWillAppear(animated: animated)
      tableView.reloadData()
    }

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

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

        cell.textLabel?.text = listItems[indexPath.row] //Then sets cell of indexPath text = lists value of index path

        return cell
    }

}

另一种选择是删除那些惰性变量并根据需要初始化这些视图控制器,以便在您将它们从堆栈中删除后释放它们。这意味着您的表格视图将始终重新加载,而无需在 ViewWillAppear 中添加任何代码

import UIKit

class List: NSObject {

    var name: String
    var items: [String?]
    var shared: String?

    init(name: String, items: [String], shared: String?) {
        self.name = name
        self.items = items
        self.shared = shared
    }

}

enum ListType {
    case apply
    case view
}

class ListViewController: UITableViewController {

    //Initialize Variables Here
    let cellId = "cellId"

    var lists: [List] = [
        List(name: "Veggies", items: ["Fruit Loops", "Pasta"], shared: nil),
        List(name: "11/17/18", items: ["Eggs", "Green Beans", "Pirate Booty", "Bread", "Milk"], shared: nil),
        List(name: "Fruits", items: ["Fruit Loops", "Oranges"], shared: nil),
        List(name: "Red Foods", items: ["Apples", "Tomatoes", "Watermelon", "Cherries"], shared: nil),
        List(name: "Grains", items: ["Bread Crumbs", "Pasta", "Rice", "Chicken Flavored Rice"], shared: nil)
    ]

    //Setup Enums and Switches
    var listType: ListType!


    override func viewDidLoad() {
        super.viewDidLoad()

        //Things that both cases have in common:
        navigationController?.navigationBar.prefersLargeTitles = true

        let addBarButtonItem = UIBarButtonItem(title: "+", style: .plain, target: self, action: #selector(newList)) //+ Button
        addBarButtonItem.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 27)!], for: .normal)
        addBarButtonItem.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 27)!], for: .selected)

        //SWITCH STATEMENT
        switch listType as ListType {

        case ListType.apply:
            //Apply Begin
            navigationItem.title = "Apply List"

            //Setup Navigation Bar Items
            let locateBarButtonItem = UIBarButtonItem(title: "Locate Item", style: .plain, target: self, action: nil)

            //Add items to navigation bar
            navigationItem.rightBarButtonItems = [addBarButtonItem, locateBarButtonItem]
            //Apply End
        case ListType.view:
            //View Begin
            //Setup Navigation Bar
            navigationItem.title = "My Lists"

            //Add items to navigation bar
            navigationItem.rightBarButtonItem = addBarButtonItem
            navigationItem.leftBarButtonItem = editButtonItem

            //View End
        }
        //SWITCH STATEMENT END


        //Register TableView with Id: cellId
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)

    }

    @objc func newList() {
        let newListVC = NewListViewController()
        newListVC.pageControlFunc(pageView: PageView.name)
        navigationController?.pushViewController(newListVC, animated: true) //Then pushes listVC
    }

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

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

        cell.textLabel?.text = self.lists[indexPath.row].name //Then sets cell of indexPath text = lists value of index path

        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let listItemsVC = ListItemsViewController()
        listItemsVC.listName = lists[indexPath.row].name
        listItemsVC.listItems = lists[indexPath.row].items
        print(listItemsVC.listItems)
        navigationController?.pushViewController(listItemsVC, animated: true)
    }

}


///////////////////////////////////////////////////////////////////////////

SECOND UITABLEVIEW - NOT UPDATING

///////////////////////////////////////////////////////////////////////////

import UIKit

class ListItemsViewController: UITableViewController {

    //Initialize Variables Here
    let cellId = "cellId1"

    var listName: String?
    var listItems: [String?] = []


    override func viewDidLoad() {
        super.viewDidLoad()

        //Things that both cases have in common:
        navigationController?.navigationBar.prefersLargeTitles = true

        //Set Title
        navigationItem.title = listName

        //Register TableView with Id: cellId
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)

        //Delegate method not called on push to view

    }

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

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

        cell.textLabel?.text = listItems[indexPath.row] //Then sets cell of indexPath text = lists value of index path

        return cell
    }

}

【讨论】:

  • 非常感谢!
  • 没问题!祝你好运:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多