将 UITableView 实例化为弹出框时,UITableViewCell 的属性为零

Posted

技术标签:

【中文标题】将 UITableView 实例化为弹出框时,UITableViewCell 的属性为零【英文标题】:UITableViewCell's attributes are nil when instantiating UITableView as a popover 【发布时间】:2016-12-01 19:16:37 【问题描述】:

我有一个UIViewController 和一个UISegmentedControl,当我单击segmentedControl 段时,我想从中显示一个UITableViewController 作为弹出框。我遇到的问题是当我点击一个片段时,弹出框开始加载,但在 myPopoverTableViewController 加载时崩溃。它崩溃了

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell,说我PopoverTableViewCell的属性是nil

为简单起见,我将在此处引用我的类:

myViewController: MyViewController
myPopoverTVController: PopoverTableViewController
myPopoverTVCell: PopoverTableViewCell

lldb 中,我检查了单元格的值dataSource,似乎唯一为零的是myPopoverTVCell 的属性,我在myPopoverTVController's viewWillAppear 中注册了以下行:

tableView.register(PopoverTableViewCell.self, forCellReuseIdentifier: "cell")

myPopoverTVController 没有通过 popover segue(尽管我已经尝试过)连接到 myViewController。我已经检查了PopoverTableViewCellmyPopoverTVController's 原型单元的类中引用。我已经仔细检查了从单元到 PopoverTableViewCell 类的连接。我检查了我在情节提要上已将 Table View Cell 的标识符设置为 cell

这是我从myViewController 开始弹出窗口的方法,紧随Apple's code:

@IBAction func segmentedControlAction(_ sender: UISegmentedControl) 
    // instantiate the PopoverTableViewController
    let popoverTVC = PopoverTableViewController()
    // set variables on it
    popoverTVC.selectedSegmentIndex = sender.selectedSegmentIndex
    popoverTVC.currentRegion = currentRegion
    // disignate presentation style as a popover
    popoverTVC.modalPresentationStyle = .popover

    present(popoverTVC, animated: true, completion: nil)

    let presentationController = UIPopoverPresentationController(presentedViewController: popoverTVC, presenting: self)
    presentationController.permittedArrowDirections = .up
    presentationController.sourceView = view
    presentationController.sourceRect = segmentedControl.frame

myPopoverTVController 上,这是我的cellForRowAt indexPath 的样子:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    // let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! PopoverTableViewCell
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PopoverTableViewCell

    // Configure the cell...
    switch selectedSegmentIndex 
    case 0, 1:
        cell.areaLabel.text = popoverStringArray[indexPath.row]

    case 2:
        let countryList = locationManager.countryList
        let countryCodes = locationManager.countryCodes

        cell.areaLabel?.text = countryList[indexPath.row]
        cell.flagLabel?.text = countryCodes[indexPath.row]

    default:
        break
    

    return cell

我检查了在myViewController 上实例化时设置的变量,它们都有值。只是tableViewCell 属性是nil--lldb 在我键入po cell 时返回单元格的内存地址。我已经设置了UITableViews 一百万次,但我无法弄清楚这件事。任何建议:非常感谢我做错了什么。我会放心,我的问题是我的一个令人吃惊的愚蠢遗漏。感谢您的阅读。

【问题讨论】:

您是否有一个具有重用标识符“cell”且类 PopoverTableViewCell 的单元格?检查重用标识符一次。 是的,这是我检查的第一件事。我几乎可以肯定这与弹出框的实例化有关,因为我已经多次配置了 TVC。 尝试像这样实例化你的 PopoverTableViewController 对象 'let controller = storyboard.instantiateViewController(withIdentifier: "someViewController") as! PopoverTableViewController 呃!在同一个地方发生同样的事故。单元格有内存地址,但标签属性为nil @Rajat 我找到了另一种给猫剥皮的方法,还清理了一堆代码。谢谢你的建议:) 【参考方案1】:

我放弃了尝试使用 Apple 的代码,并想出了一种替代方法来让弹出框工作。

我在故事板中的ctrl+dragged 从我的myViewControllermyPopoverTVController。我将 segue 标识符 设置为 popoverSegue 并将其设置为显示为弹出框。我还指定了一个锚点。

从那里,我删除了segmentedControlAction() 中的代码,并将其替换为以下内容:

@IBAction func segmentedControlAction(_ sender: UISegmentedControl) 

    self.performSegue(withIdentifier: "popoverSegue", sender: segmentedControl.selectedSegmentIndex)


我在myViewController 上的prepareForSegue 中添加了以下代码:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "popoverSegue" 
        let destinationViewController = segue.destination as! PopoverTableViewController
        destinationViewController.selectedSegmentIndex = sender as! Int
        destinationViewController.currentRegion = currentRegion


        let popoverController = destinationViewController.popoverPresentationController

        if popoverController != nil 
            popoverController?.delegate = self
        
    

我还向myViewController 添加了一个带扩展名的委托方法:

extension MyViewController: UIPopoverPresentationControllerDelegate 
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle 
        return .none
    

最后,我在myPopoverTVController 中取出了对数据源的本地引用,所以它现在看起来像这样:

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

    // Configure the cell...
    switch selectedSegmentIndex 
    case 0:
        cell.areaLabel.text = locationManager.cityList(geographicRegion: currentRegion!)[indexPath.row]
        cell.flagLabel.isHidden = true

    case  1:
        cell.areaLabel.text = locationManager.stateList(geographicRegion: currentRegion!)[indexPath.row]
        cell.flagLabel.isHidden = true

    case 2:
        cell.areaLabel?.text = locationManager.countryList[indexPath.row]
        cell.flagLabel?.text = locationManager.countryCodes[indexPath.row].flag()

    default:
        break
    

    return cell

...它奏效了。

结束 ;)

【讨论】:

以上是关于将 UITableView 实例化为弹出框时,UITableViewCell 的属性为零的主要内容,如果未能解决你的问题,请参考以下文章

当 UIViewController 显示弹出框时,更改 CALayer 颜色与 UIView tintColor 同步

显示弹出框时更改方向时应用程序崩溃。

单击外部弹出框时如何防止 UIPopoverPresentationController 被关闭?

Swift - 呈现已呈现的弹出框时应用程序崩溃

在 iOS 8 中呈现弹出框时如何使屏幕模糊

在 iPhone 6 Plus 上关闭 UISplitViewController 弹出框时 UIWebView 被拉伸