【问题标题】:ios swift tableview not showing custom cellsios swift tableview不显示自定义单元格
【发布时间】:2019-08-21 13:34:09
【问题描述】:

我正在尝试在 iOS 应用程序中使用 Storyboard 布局中的自定义单元格创建表格视图。

但由于某种原因,表格单元格没有显示出来。当我尝试设置调试断点时,我发现调试器正在达到这个功能

public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

但它永远不会达到这个功能 -

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

这是我的视图控制器代码 -

extension NavigationViewController: UITableViewDataSource, UITableViewDelegate, SideMenuControllerDelegate {

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

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuTableItem", for: indexPath as IndexPath) as! SideMenuTableItem
        cell.setItemData(items[indexPath.row])
        return cell
    }

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

    func setupTableViews() {
        menuTable.register(SideMenuTableItem.self, forCellReuseIdentifier: "SideMenuTableItem")

    }
}

class SideMenuTableItem: UITableViewCell {

    @IBOutlet weak var menuImage: UIImageView!
    @IBOutlet weak var menuLabel: UILabel!

    var data: MenuItem?

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    func setItemData(_ item: MenuItem) {
        data = item
        menuLabel.text = data?.title
        if data?.icon_res != nil {
            menuImage.image = UIImage(named: (data?.icon_res)!)
        }
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

我已经在情节提要中检查了我已将可重用标识符设置为表格原型单元格,并将数据源和委托属性连接到表格视图

在创建 items 数组后,我在 viewDidLoad() 函数中调用 setupTableViews() 方法 但我仍然无法让细胞出现在我的视野中。 谁能建议我在这里遗漏了什么或我的代码有什么问题,或者我该如何进一步调试这个问题

import UIKit
import SideMenuSwift

class NavigationViewController: UIViewController {

    @IBOutlet weak var navigationContainer: UIView!
    @IBOutlet weak var emailButton: UIButton!
    @IBOutlet weak var phoneButton: UIButton!
    @IBOutlet weak var userAvatar: UIImageView!
    @IBOutlet weak var userProfile: UIButton!
    @IBOutlet weak var userName: UILabel!
    @IBOutlet weak var menuTable: UITableView!

    var service: AuthenticationService!
    var cdc: CoreDataController!
    var items: [MenuItem] = []
    var currentUser: User?

    override func viewDidLoad() {
        super.viewDidLoad()
        setupSidebar()
        initSidebarData()
        setupUserHeader()
        setupTableViews()
    }

    func setupUserHeader() {
        if currentUser != nil {
            if currentUser?.name != nil {
                userName.text = currentUser?.name
            } else if currentUser?.role != nil {
                userName.text = "urTutors " + (currentUser?.role ?? "")
            }
            if currentUser?.avatarUrl != nil {
                userAvatar.downloaded(from: (currentUser?.avatarUrl)!)
            }
        }
    }

    func initSidebarData() {
        service = AuthenticationServiceProvider()
        cdc = CoreDataController()
        items = cdc.getNavigationData()
        currentUser = cdc.getUserData()
    }

    func setupSidebar() {
        self.view.backgroundColor = UIColor.hexColor("#fff")
        navigationContainer.backgroundColor = UIColor.hexColor("#2a2a2a")
        SideMenuController.preferences.basic.statusBarBehavior = .hideOnMenu
        SideMenuController.preferences.basic.position = .above
        SideMenuController.preferences.basic.direction = .left
        SideMenuController.preferences.basic.enablePanGesture = true
        SideMenuController.preferences.basic.menuWidth = 275
        sideMenuController?.delegate = self
    }

    static func createViewController() -> NavigationViewController {
        let sb = UIStoryboard(name: "StudentHomeModuleStoryboard", bundle: nil)
        let vc = sb.instantiateViewController(withIdentifier: "NavigationViewController")
        return vc as! NavigationViewController
    }
}

--更新--

更新 setupTableLayout 功能 -

func setupTableViews() {
        let bundle = Bundle(for: type(of: self))
        let cellNib = UINib(nibName: "SideMenuTableItem", bundle: bundle)
        menuTable.register(cellNib, forCellReuseIdentifier: "SideMenuTableItem")
        menuTable.register(SideMenuTableItem.self, forCellReuseIdentifier: "SideMenuTableItem")
        menuTable.reloadData()
    }

【问题讨论】:

  • 是的,我尝试搜索并遵循许多可用的指南,但我仍然无法使其正常工作,因此在这里发布帖子
  • items.count 返回什么?如果为零,则不会调用cellForRow
  • 你在哪里调用reloadData?在您致电setupTableViews之后?
  • 为什么需要 setupTableViews()?您是否使用 xib 文件来创建 tableViewCell?您似乎没有 xib 文件。
  • 等一下。您的自定义类正在使用插座,但您正在使用 setupTableViews 中的注册调用,该调用采用类,而不是 nib 名称。你不能使用没有笔尖或故事板的插座。这就是为什么您的网点为零并且您正在崩溃的原因。使用 xib 或以编程方式创建标签。

标签: ios swift uitableview cocoa-touch tableview


【解决方案1】:

在这个问题上聊天后,我们发现有两个问题。

第一个问题是上面提到的缺少reloadData 调用。这导致cellForRow 未被调用。添加reloadData 纠正了该问题,但随后自定义单元类的出口为零,导致setItemData 崩溃。

第二个问题是 register(_:forCellReuseIdentifier:) 在代码中被调用,但自定义单元已设置为 Interface Builder UITableView 声明的一部分。在自定义类上再次调用 register 会重新注册 reuseIdentifier,断开情节提要中设置的插座。

删除register 调用并添加reloadData 解决了所有问题。

【讨论】:

    【解决方案2】:

    你永远不会打电话给setupTableViews()。您的代码应如下所示:

    class NavigationViewController: UIViewController, SideMenuControllerDelegate {
    
    override func viewDidLoad() {
            super.viewDidLoad()
    
            setupTableViews()
        }
    
    func setupTableViews() {
    menuTable.reloadData()
        }
    }
    
    extension NavigationViewController: UITableViewDataSource, UITableViewDelegate {
    
        public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return items.count
        }
    
        public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuTableItem", for: indexPath as IndexPath) as! SideMenuTableItem
            cell.setItemData(items[indexPath.row])
            return cell
        }
    
        public func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
    }
    

    你永远不会调用函数,也不会调用 viewDidLoad。这应该会有所帮助。此外,您的视图控制器代码的其余部分在哪里(这就是全部吗?它不应该是!)。

    您不需要注册您的单元,因为您请求它并确保您 reloadData()。

    希望这会有所帮助!

    【讨论】:

    • 是的,我在videDidLoad中调用了这个setupTableViews方法。用其余的控制器代码更新了帖子
    • 请在setupTableViews()函数中注册您的单元后尝试调用menuTable.reloadData()。就像我的回答一样。
    • 是的,reloadData 似乎有帮助。但现在我在表格单元类的这一行中得到“线程 1:致命错误:在展开可选值时意外发现 nil” - menuLabel.text = data?.title
    • 好的,现在问题是data?.title 不存在。您需要确保它存在,否则只返回一个空字符串。看起来cdc.getNavigationData() 中的一些数据没有正确返回到数组中。
    • 它存在,我已经检查过,menuTable 也是如此。我什至尝试使用 if data?.title != nil { menuLabel.text = data?.title } 但再次遇到同样的错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 2016-04-21
    相关资源
    最近更新 更多