Ios Swift 3 button.addTarget未在所有表格单元格上工作

Ios Swift 3 button.addTarget未在所有表格单元格上工作,ios,swift,swift3,Ios,Swift,Swift3,我创建了一个应用程序,允许用户根据评论存储各种录音。当我显示这张表时,数据将填充以下代码: func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let row = (indexPath as NSIndexPath).item let cell = tableView.dequeueReusableCell(withIdentifie

我创建了一个应用程序,允许用户根据评论存储各种录音。当我显示这张表时,数据将填充以下代码:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let row = (indexPath as NSIndexPath).item
    let cell = tableView.dequeueReusableCell(withIdentifier: "voiceRecordingCell", for: indexPath) as! VoiceRecordingTableViewCell
    let voiceRecording = self.voiceRecordings[row] as! NSDictionary

    let isoFormatter = DateFormatter()
    isoFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'.000Z'"
    let createdAt = isoFormatter.date(from: voiceRecording["created_at"] as! String)
    self.recordingIndexPaths.insert(indexPath, at: row)

    cell.recording = voiceRecording
    cell.date.text = getDateFormatter("dd-MM-y").string(from: createdAt!)
    cell.time.text = getDateFormatter("HH:mm").string(from: createdAt!)
    cell.length.text = voiceRecording["length"] as? String
    cell.location.text = voiceRecording["location"] as? String

    let audioPlayerController = self.storyboard?.instantiateViewController(withIdentifier: "AudioPlayerController") as! AudioPlayerController

    audioPlayerController.voiceRecording = voiceRecording

    cell.audioPlayer.addSubview(audioPlayerController.view)
    self.addChildViewController(audioPlayerController)
    audioPlayerController.didMove(toParentViewController: self)

    cell.deleteRecordingButton.tag = row
    cell.deleteRecordingButton.addTarget(self, action: #selector(deleteRecordingPressed(_:)), for: .touchUpInside)

    return cell
}
所有单元格似乎都正确呈现,但是对于最初未随页面呈现的单元格,我必须向下滚动才能查看这些单元格,当我单击音频播放器控件上的按钮或
deleteRecordingButton
时,什么都没有发生,就好像没有设置
addTarget
。设置按钮的代码正在被调用,不会产生错误,只是不适用于这些按钮

最初显示在屏幕上的按钮具有正确的操作,并且所有操作都非常有效,因此我知道这是可行的

我真的不知道是什么导致了这一切。我试过搜索google和stackoverflow,但什么也没找到。这方面的任何援助都将得到极大的帮助

---------------更新-----------

我只是试着把一些断点放进去

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

}

这也只适用于顶部2个单元格或顶部1个单元格(如果在景观中)

由于单元格一直被重用,因此引用丢失。 试着这样做:

class ButtonTableViewCell: UITableViewCell {

    typealias TapClosure = () -> Void

    var buttonTapped: TapClosure?

    @IBAction func buttonTouchUpInside(sender: UIButton) {
        buttonTapped?()
    }

}

extension TestViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let cell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath) as! ButtonTableViewCell

        cell.buttonTapped = {
            print("Button tapped")
        }

        return cell
    }

}

再来一杯。永远不要在CellForRowatineXpath中初始化日期格式化程序。而是在viewDidLoad或静态结构中创建它以供重用。

因为单元格在引用丢失的所有时间都被重用。 试着这样做:

class ButtonTableViewCell: UITableViewCell {

    typealias TapClosure = () -> Void

    var buttonTapped: TapClosure?

    @IBAction func buttonTouchUpInside(sender: UIButton) {
        buttonTapped?()
    }

}

extension TestViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let cell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath) as! ButtonTableViewCell

        cell.buttonTapped = {
            print("Button tapped")
        }

        return cell
    }

}

再来一杯。永远不要在CellForRowatineXpath中初始化日期格式化程序。相反,在viewDidLoad或静态结构中创建它以供重用。

最后,我已经解决了这个问题

之所以会发生这种情况,是因为我使用了scrollview with来上下滚动表格,而没有使用表格本机滚动功能

使用“表格滚动”功能时,按钮会在动作进入视图时应用于动作。这是通过
func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
方法处理的。但是,当您按照我的方式进行操作时,它最初会渲染所有单元格和屏幕外的单元格,但这些单元格不起作用


用这种方式工作有点烦人,但至少我现在知道了。

我终于明白了

之所以会发生这种情况,是因为我使用了scrollview with来上下滚动表格,而没有使用表格本机滚动功能

使用表格滚动功能时,按钮将应用于将其带入视图的操作。这由
func tableView(\utableview:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell处理{
方法。但是,当您按照我最初的方式进行操作时,它会渲染所有单元格和屏幕外的单元格,但这些单元格不起作用



以这种方式工作有点烦人,但至少我现在知道了。

这里没有其他问题。只能通过此方法创建单元格,因此必须在新单元格上调用添加目标。没有达到目标处理程序方法中的断点?例如,我在表中有3行。当我打开页面时ddTarget方法被调用了3次,但是只有2个可见的按钮起作用。是的,我明白你的意思。因此,在这种情况下,当你点击第3个按钮时,你的
deleteRecordingPressed
功能根本不会通过设置断点触发?完全没有,但如果我按下另外2个按钮,它就可以正常工作。我确实注意到当我有了sc绿色在横向中只有前1个可以工作,其他的会被破坏,这就是为什么我认为这与未显示的按钮有关cell.deleteRecordingButton.addTarget(self,action:#selector(YourViewController.deleteRecordingPressed(:),for:.touchUpInside)请尝试此操作。其他错误不在此处。只能通过此方法创建单元格,因此必须在新单元格上调用添加目标。未达到目标处理程序方法中的断点?例如,我在一个表中有3行。当我打开页面时,会调用addTarget方法3次,但只有2个按钮是可见的e工作。是的,我明白你的意思。因此,在这种情况下,当你点击第三个按钮时,设置断点根本不会触发你的
deleteRecordingPressed
功能?完全不会,但如果我按下另外两个按钮,它就可以正常工作。我确实注意到,当我将屏幕置于横向时,只有顶部的1个按钮可以工作,其他的1个按钮将被破坏这就是为什么我认为这与未显示的按钮有关cell.deleteRecordingButton.addTarget(self,action:#selector(YourViewController.deleteRecordingPressed(:)),for:.touchUpInside)尝试此操作重新使用单元格,然后再次添加目标引用。请仔细查看
cellForRowAt
Ah,这是有道理的,并且会导致我遇到的问题,我将对此进行测试,并让您知道它是否有效。谢谢:)@SWIE我可以确认此操作不起作用,谢谢您的努力,尽管我已将数据格式化程序实例移入正如你所解释的那样,对于viewDidLoad方法来说,这确实更有意义。单元格被重用,然后再次添加目标引用。仔细查看
cellForRowAt
Ah,这是有意义的,并且会导致我遇到的问题,我将测试它,并让你知道它是否有效。谢谢:)@SWIE我可以确认这不起作用,谢谢您可能认为,正如您所解释的,我确实将数据格式化程序实例移动到了viewDidLoad方法中,这确实更有意义。