Swift - TableView将IndexPath返回为nil

时间:2017-10-07 07:26:46

标签: ios swift uitableview

我目前正在尝试在swift中编写动态表格,当我点击表格中的按钮时,我目前无法识别表格。

我的一般意图是:

我有一个带有按钮和标签的表格视图设置,这样每次我从数据库中提取名称/序列号时,它将填充一个表格行,其中包含隐藏的序列号字段和按钮。当我按下其中一个按钮(例如查看或编辑)时,该按钮将从该按钮转到新页面,并将序列号传递到该新页面。

除了传递序列号时的最后一位,此表工作正常。

在下面的代码中,您将看到该行 let indexpath = self.tableView.indexPathForSelectedRow

调试时,它返回nil而不是我需要用户点击哪一行的信息。我已经在互联网上搜索了很多内容,我根本不知道为什么它会返回nil,因为几乎所有关于prepareforsegue中代码的演示都表明这应该没有任何问题。

import UIKit

class FriendsListTableViewController: UITableViewController
{
    var FriendName = [String]()
    var FriendSerialNumber = [String]()
    var Name: String = ""
    let cellReuseIdentifier = "FriendNameRow"

    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.tableView.register(FriendsListTableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)

        let appDelegate = UIApplication.shared.delegate as! AppDelegate

        FriendName = appDelegate.getAllFriendsNames()

        FriendSerialNumber = appDelegate.getAllFriendsSerialNumbers()
        tableView.estimatedRowHeight = 40
    }

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

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

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

        let row = indexPath.row
        cell.FriendLabel?.text = FriendName[row]
        cell.FriendSerialLabel?.text = FriendSerialNumber[row]
        return cell
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        let indexpath = self.tableView.indexPathForSelectedRow
        if segue.identifier == "AddFriendSegue"
        {
            let EditFriendController: EditFriendViewController = segue.destination as! EditFriendViewController

            EditFriendController.IsAddRecord = true
        }

        else if segue.identifier == "FriendViewSegue"
        {
            let FriendController: SingleFriendViewController = segue.destination as! SingleFriendViewController

            let SerialNumberToPass = self.FriendSerialNumber[0]

            FriendController.TheSerialNumber = SerialNumberToPass
        }
        else if segue.identifier == "EditFriendSegue"
        {
            let SerialNumberToPass = self.FriendSerialNumber[0]
            let EditFriendController: EditFriendViewController = segue.destination as! EditFriendViewController

            EditFriendController.TheSerialNumber = SerialNumberToPass
            EditFriendController.IsAddRecord = false
        }
    }

}

如果需要,我也有表格单元格代码。

import UIKit

class FriendsListTableViewCell: UITableViewCell
{
    @IBOutlet weak var FriendLabel: UILabel!
    @IBOutlet weak var FriendSerialLabel: UILabel!

    @IBAction func ViewButton(_ sender: Any)
    {
    }
    @IBAction func EditButton(_ sender: Any)
    {
    }
    @IBAction func DeleteButton(_ sender: Any)
    {
        let TheSerialNumber = FriendSerialLabel.text
        let appDelegate = UIApplication.shared.delegate as! AppDelegate        
        appDelegate.DeleteFriend(SerialNumber: TheSerialNumber!)
    }

    override func awakeFromNib()
    {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool)
    {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }


}

如果您需要其他信息,请告诉我们。

1 个答案:

答案 0 :(得分:1)

正如我在评论中提到的,我个人会使用UITableViewCell中的委托方法:

在我们开始之前,我建议您将Friend数据放入模型中,以使生活更轻松,例如:

struct Friend {
  var name: String?
  var serialNumber: String?
}

这种方式,每当您需要数据时,您只需要一个Array<Friend>。在您UITableViewCell被叫朋友中添加一个变量,您可以在每次初始化时设置该变量。

var friend: Friend? {
   didSet {
     friendLabel.text = friend?.name
     friendSerialLabel.text = friend?.serialNumber
   }
}

位于FriendsListTableViewCell

的顶部
protocol FriendsListTableViewCellDelegate {
  func willView(_ friend: Friend?)
  func willEdit(_ friend: Friend?)
  func willDelete(friend: Friend?)
}

FriendsListTableViewCell

中添加其他媒体资源
var delegate: FriendsListTableViewCellDelegate?

然后,您可以从@IBAction

中调用这些内容
@IBAction func ViewButton(_ sender: Any) {
    delegate?.willView(friend)
}
@IBAction func EditButton(_ sender: Any) {
    delegate?.willEdit(friend)
}
@IBAction func DeleteButton(_ sender: Any) {
    delegate?.willDelete(friend)
}

返回tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)将您的视图控制器指定为单元格的代理:

cell.delegate = self

此时您将收到错误,因为您尚未符合视图控制器中的协议。

extension FriendsListTableViewController: FriendsListTableViewCellDelegate {
  func willView(_ friend: Friend?) {
    // View your friend
  }

  func willEdit(_ friend: Friend?) {
    // Edit your friend
  }

  func willDelete(friend: Friend?) {
    // Delete your friend
  }
}

在委托方法中实例化视图控制器并推送/显示它。向推送的视图控制器添加一个新属性,并使用委托方法中的变量进行设置:

var friend: Friend?

希望你应该拥有你需要的一切。