Ios 获取单元格的问题';使用自定义UITableViewCell中的按钮创建字符串

Ios 获取单元格的问题';使用自定义UITableViewCell中的按钮创建字符串,ios,iphone,swift,xcode,uitableview,Ios,Iphone,Swift,Xcode,Uitableview,我正试图使用自定义UITableViewCell中的按钮获取单元格的string。但当我点击按钮时,应用程序因此错误而崩溃: 致命错误:在展开可选值时意外发现nil 我尝试了打印一些东西,效果很好!。但当我尝试获取其他单元格的字符串时,应用程序崩溃。这是我的密码: func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cellID:St

我正试图使用自定义
UITableViewCell
中的按钮获取单元格的
string
。但当我点击按钮时,应用程序因此错误而崩溃:
致命错误:在展开可选值时意外发现nil

我尝试了
打印
一些东西,效果很好!。但当我尝试获取其他单元格的字符串时,应用程序崩溃。这是我的密码:

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

  var cellID:String!
      var cell = OrderCell()

      switch indexPath.section {
          .
          .
          .
          .
          .

       case 5 :
         if indexPath.row == 0  {cellID = "Submit" }
        cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! OrderCell


        cell.submitButton.addTarget(self, action: #selector(OrderViewController.submitNewOrder), for: .touchUpInside)

      default:
         break
      }
  return cell

   }



  func submitNewOrder() {
       //Title
      let index1:IndexPath = IndexPath(row: 0, section: 0)
      let cell1: OrderCell = tableView.cellForRow(at: index1) as! OrderCell
      print("order is \(cell1.orderTitle.text!)")

}
我确信
是正确的!。另外,我对
@IBAction
使用了相同的方法,效果很好!有什么问题

谢谢你

你需要的是

self.tableView(tableView, cellForRowAt: index1)
而不是

tableView.cellForRow(at: index1) as! OrderCell
它是如何工作的???

在tableview中,单元格得到重用。只有滚动tableview,然后点击底部某个单元格中的按钮,代码才会崩溃,原因是索引路径(0,0)处的单元格被重用,因此tableview不会将单元格保持在索引路径(0,0)处,因此当调用
self.tableview(tableview,cellForRowAt:index1)
时,它返回零

另一方面,您可能应该要求数据源代理返回单元格,而不是tableView本身。在本例中,您自己的VC是数据源,因此我编写了

self.tableView(tableView, cellForRowAt: index1)
这将在索引路径(0,0)处获取对单元格的引用,即使它不在tableView中,并将其移交给u,而不是nil:)

建议:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
虽然上面的代码工作得非常好,但我个人建议在每个单元格之间使用iAction,因为单元格中有按钮,所以在单元格中而不是在tableViewController中创建按钮的iAction在逻辑上是合理的

您始终可以在单元格中声明一个委托,并在TableViewController中实现它,以通知按钮点击并告知点击了哪个按钮

这样,代码对任何人来说都是干净的,哪怕只看一次。单元格负责处理其子视图的iAction,只通知tableViewController点击按钮时要做什么。另一方面,TableViewController只执行任务,而不必担心点击了哪个按钮

编辑:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
我无法更改任何可以使用现有代码的内容,如上图所示:)只需替换cellForRowAt:)

编辑2:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
尽管上面提供的代码工作得非常好,但在我们的一次聊天中(您可以参考注释部分的聊天),我意识到indexath(0,0)中的单元格有一个textfield

尽管上述解决方案对label很有效,但在将其与TextField一起使用时,它将TextField.text返回为“”

这显然是因为cellForRowAtIndexPath中的错误以及UITableView的单元重用策略

虽然我在上述答案的建议部分提出了正式和更恰当的建议,但我相信,由于答案已被接受,我有责任提供功能齐全的代码,这些代码也将与textField一起使用:)

最简单的方法是,一旦用户在indexPth(0,0)的cell的textField中输入一些文本,就更新数据源,并在tableView的cellForRowAt索引路径中正确更新textField文本

在向下滚动或重新使用单元格时,正确操作将不再将文本字段文本返回为“”

我是这样做的:)

第1步:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
使您的单元格成为textField委托并实现TextFieldDiEndediting:)

第二步:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
在自定义单元格中声明协议,以通知tableViewController使用用户文本更新其数据源:)

第三步:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
在单元格中创建委托:)

第4步:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
实现textfielddidediting

func textFieldDidEndEditing(_ textField: UITextField) {
    self.delegate?.updateDataSource(with: textField.text!)
}
第五步:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
确认ViewController(TableViewController)中的代理

最后将CellForRowatineXpath更新为

        cell.delegate = self
        if indexPath.row == 0 && self.userEnterredText != nil {
            cell.testTextField.text = self.userEnterredText!
        }
        else {
            cell.testTextField.text = ""
        }
        return cell
这将确保当您在重复使用的单元格的数据源上调用
self.tableView(tableView,cellForRowAt:index1)
时,为索引路径处的行调用单元格,并且由于您在cellForRowAt中的代码,您的文本字段将正确填充:)

现在您仍然可以使用您的代码

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1: OrderCell = tableView.cellForRow(at: index1) as! OrderCell
print("order is \(cell1.orderTitle.text!)")
还有文本字段:)

希望有帮助:)

您所需要的是

self.tableView(tableView, cellForRowAt: index1)
而不是

tableView.cellForRow(at: index1) as! OrderCell
它是如何工作的???

在tableview中,单元格得到重用。只有滚动tableview,然后点击底部某个单元格中的按钮,代码才会崩溃,原因是索引路径(0,0)处的单元格被重用,因此tableview不会将单元格保持在索引路径(0,0)处,因此当调用
self.tableview(tableview,cellForRowAt:index1)
时,它返回零

另一方面,您可能应该要求数据源代理返回单元格,而不是tableView本身。在本例中,您自己的VC是数据源,因此我编写了

self.tableView(tableView, cellForRowAt: index1)
这将在索引路径(0,0)处获取对单元格的引用,即使它不在tableView中,并将其移交给u,而不是nil:)

建议:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
虽然上面的代码工作得非常好,但我个人建议在每个单元格之间使用iAction,因为单元格中有按钮,所以在单元格中而不是在tableViewController中创建按钮的iAction在逻辑上是合理的

您始终可以在单元格中声明一个委托,并在TableViewController中实现它,以通知按钮点击并告知点击了哪个按钮

这样,代码对任何人来说都是干净的,哪怕只看一次。单元格负责处理其子视图的iAction,只通知tableViewController点击按钮时要做什么。另一方面,TableViewController只执行任务,而不必担心点击了哪个按钮

编辑:

let index1:IndexPath = IndexPath(row: 0, section: 0)
let cell1 = self.tableView(tableView, cellForRowAt: index1) as! OrderCell
我无法更改任何可以使用现有代码的内容,如上图所示:)只需替换cellForRowAt:)