UITableViewCell's attributes are nil when instantiating UITableView as a popover

倖福魔咒の 提交于 2019-12-24 00:26:39

问题


I have a UIViewController with a UISegmentedControl from which I'd like to present a UITableViewController as a popover when I click on a segmentedControl segment. The issue I'm having is the moment I click on a segment, the popover starts to load, but crashes as myPopoverTableViewController loads. It crashes in

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell, saying the attributes of my PopoverTableViewCell are nil.

For simplicity's sake, I'll reference my classes here:

myViewController: MyViewController
myPopoverTVController: PopoverTableViewController
myPopoverTVCell: PopoverTableViewCell

In lldb, I checked for the values of the cell, the dataSource, and it seems the only thing that's nil are the the attributes of myPopoverTVCell, which I register in myPopoverTVController's viewWillAppear with the following line:

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

myPopoverTVController is not connected via a popover segue (though I've tried that) to myViewController. I've checked that I have PopoverTableViewCell referenced in the class for myPopoverTVController's prototype cell. I've double checked the connections from the cell to to the PopoverTableViewCell class. I checked that I've got the Table View Cell's identifier set to cell on the storyboard.

Here's how I begin the popover from myViewController, following 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
}

On myPopoverTVController, here's what my cellForRowAt indexPath looks like:

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
}

I checked the variables that are set upon instantiation on myViewController and they've all got values. It's just the tableViewCell attributes that are nil--lldb returns a memory address for the cell when I type po cell. I've set up UITableViews a million times, but I can't figure this thing out. Any suggestions re: what I'm doing wrong are greatly appreciated. I'll rest assured my problem is a startlingly silly omission on my part. Thank you for reading.


回答1:


I threw in the towel trying to use Apple's code and figured out an alternative method to get the popover to work.

I ctrl+dragged in storyboard from my myViewController to myPopoverTVController. I set the segue identifier to popoverSegue and set it to display as a popover. I also specified an anchor point.

From there, I gutted the code in segmentedControlAction() to replaced it with the following:

@IBAction func segmentedControlAction(_ sender: UISegmentedControl) {

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

}

I added the following code to my prepareForSegue on myViewController:

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
        }
    }
}

I also added a delegate method to myViewController with an extension:

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

Lastly, I took out a local reference to the data source in myPopoverTVController so it now looks like this:

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
}

...and it worked.

The End ;)



来源:https://stackoverflow.com/questions/40918663/uitableviewcells-attributes-are-nil-when-instantiating-uitableview-as-a-popover

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