Ios 查找单元格索引路径时,Self为nil

Ios 查找单元格索引路径时,Self为nil,ios,swift,tableview,Ios,Swift,Tableview,我有一个使用表格视图的应用程序,每个表格视图单元格中有两个文本字段:cellTitle和cellDescription。我想知道编辑任何一个文本字段后,单元格的indexpath是什么。我必须将该数据传递给viewController,以便将该数据保存在单元格数组中。当我每次测试运行它时,self是nil,这会停止代码,我无法找到方法让viewController知道编辑了什么单元格编号。有人能帮我找到编辑过的textfield单元格的单元格indexPath吗 仪表板单元格。swift imp

我有一个使用表格视图的应用程序,每个表格视图单元格中有两个文本字段:cellTitle和cellDescription。我想知道编辑任何一个文本字段后,单元格的indexpath是什么。我必须将该数据传递给viewController,以便将该数据保存在单元格数组中。当我每次测试运行它时,self是nil,这会停止代码,我无法找到方法让viewController知道编辑了什么单元格编号。有人能帮我找到编辑过的textfield单元格的单元格indexPath吗

仪表板单元格。swift

import UIKit
protocol cellInfoDelegate {
    func tableCellInfo(title: String?, description: String?, cell: DashboardCell)

}

class DashboardCell: UITableViewCell {

    var indexpathInstance = IndexPath()

    //MARK: Outlets

    @IBOutlet weak var cellTitle: UITextField!

    @IBOutlet weak var cellDescription: UITextField!

    @IBAction func cellTitleEdited(_ sender: Any) {


        if cellTitle.text != nil {
            // ERROR HERE: self is nil
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        } else {
            cellTitle.text = "Untitled"
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        }


            }



    @IBAction func cellDescriptionEdited(_ sender: Any) {
        if cellDescription.text != nil  {
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        } else {
            cellDescription.text = "Add a description Here"
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        }
    }

    let cellInformationDelegate: cellInfoDelegate! = nil


    func setDashboardCell (cell: Dashboard) {
        cellTitle.text = cell.title
        cellDescription.text = cell.desccription
    }






}
import UIKit

class DashboardViewController: UIViewController, cellInfoDelegate, UITableViewDataSource, UITableViewDelegate  {

    var events: [Dashboard] = []

    @IBOutlet weak var DashboardAdd: UIButton!
    @IBOutlet weak var tableView: UITableView!    
    @IBAction func DashboardAddA(_ sender: Any) {
        events.append(Dashboard(title: "Untitled", description: "Add A Description Here"))
        tableView.reloadData()
    }



    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        self.hideKeyboardWhenTappedAround()
    }


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


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let Dcells = events[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "DashboardCell") as! DashboardCell
        cell.setDashboardCell(cell: Dcells)
        return cell
    }


    func tableCellInfo(title: String?, description: String?, cell: DashboardCell) {
        let indexPath = (self.tableView.indexPath(for: cell)?.row)!
        print("At row \(indexPath), the title is \(title), and the description is \(description)")

        if title != "" && description != "" {
        events[indexPath] = Dashboard(title: (title)!, description: (description)!)
        } else if title != "" && description == "" {
            events[indexPath] = Dashboard(title: (title)!, description: "")

        } else if title == "" && description != "" {
            events[indexPath] = Dashboard(title: "", description: (description)!)

        } else {
            events[indexPath] = Dashboard(title: "", description: "")

        }
    }


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

    func getCellNumber (cell: DashboardCell) -> Int?{
        let indexPath = self.tableView.indexPath(for: cell)
        return indexPath?.row
    }

    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer =     UITapGestureRecognizer(target: self, action:    #selector(self.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard() {
        view.endEditing(true)
    }



}
仪表板视图控制器。swift

import UIKit
protocol cellInfoDelegate {
    func tableCellInfo(title: String?, description: String?, cell: DashboardCell)

}

class DashboardCell: UITableViewCell {

    var indexpathInstance = IndexPath()

    //MARK: Outlets

    @IBOutlet weak var cellTitle: UITextField!

    @IBOutlet weak var cellDescription: UITextField!

    @IBAction func cellTitleEdited(_ sender: Any) {


        if cellTitle.text != nil {
            // ERROR HERE: self is nil
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        } else {
            cellTitle.text = "Untitled"
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        }


            }



    @IBAction func cellDescriptionEdited(_ sender: Any) {
        if cellDescription.text != nil  {
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        } else {
            cellDescription.text = "Add a description Here"
            cellInformationDelegate.tableCellInfo(title: cellTitle.text, description: cellDescription.text, cell: self)
        }
    }

    let cellInformationDelegate: cellInfoDelegate! = nil


    func setDashboardCell (cell: Dashboard) {
        cellTitle.text = cell.title
        cellDescription.text = cell.desccription
    }






}
import UIKit

class DashboardViewController: UIViewController, cellInfoDelegate, UITableViewDataSource, UITableViewDelegate  {

    var events: [Dashboard] = []

    @IBOutlet weak var DashboardAdd: UIButton!
    @IBOutlet weak var tableView: UITableView!    
    @IBAction func DashboardAddA(_ sender: Any) {
        events.append(Dashboard(title: "Untitled", description: "Add A Description Here"))
        tableView.reloadData()
    }



    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        self.hideKeyboardWhenTappedAround()
    }


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


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let Dcells = events[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "DashboardCell") as! DashboardCell
        cell.setDashboardCell(cell: Dcells)
        return cell
    }


    func tableCellInfo(title: String?, description: String?, cell: DashboardCell) {
        let indexPath = (self.tableView.indexPath(for: cell)?.row)!
        print("At row \(indexPath), the title is \(title), and the description is \(description)")

        if title != "" && description != "" {
        events[indexPath] = Dashboard(title: (title)!, description: (description)!)
        } else if title != "" && description == "" {
            events[indexPath] = Dashboard(title: (title)!, description: "")

        } else if title == "" && description != "" {
            events[indexPath] = Dashboard(title: "", description: (description)!)

        } else {
            events[indexPath] = Dashboard(title: "", description: "")

        }
    }


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

    func getCellNumber (cell: DashboardCell) -> Int?{
        let indexPath = self.tableView.indexPath(for: cell)
        return indexPath?.row
    }

    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer =     UITapGestureRecognizer(target: self, action:    #selector(self.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard() {
        view.endEditing(true)
    }



}

首先,你需要改变

let cellInformationDelegate: cellInfoDelegate! = nil
致:

然后需要在(cellForRowAt indexPath:)中设置委托(请原谅psuedo代码):

您忘记设置委托,因此没有调用委托方法。您也没有设置索引XPath。因此,您还需要添加:

cell.indexPathInstance = indexPath

委托必须是弱属性。更改让cellInformationDelegate:cellInfoDelegate!到cellInformationDelegate:cellInfoDelegate?您还忘记设置委托属性。在let cell=tableView.dequeueReusableCell(标识符为:“DashboardCell”)之后为!仪表板单元格添加单元格。cellInformationDelegate=self
cellInformationDelegate
不应使用
声明。并且单元格不应该有自己的索引路径属性。单元格永远不需要知道自己的索引路径。@rmaddy我不会说永远?如果需要知道包含调用委托方法的textfield的单元格的indexPath,该怎么办?我已经看过很多次了,老实说,我自己也曾使用过。你会怎么做?是的,这里不需要bang操作符,因为它被设置为nil,但可能他不想让它作为可选的,也不想以后打开,为什么单元格需要知道文本字段的索引路径?最大的问题是,如果可以插入、删除或移动行,索引路径可能会出错。@rmaddy是的,我肯定看到有问题。那么,跟踪indexath的最佳解决方案是什么?这是出于好奇。我的回答是基于他的问题,不重写他的代码。