UITableViewCell 按钮标签 return 需要 UISearchController 中的 IndexPath,而不是 FetchedResultsController

UITableViewCell button tags return desired IndexPath in UISearchController, not FetchedResultsController

我在 Swift 2.0 的核心数据项目中的 UITableView 上实现了 NSFetchedResultsController。此外,我还实施了 UISearchController。除了我在自定义 UITableViewCell 按钮上遇到的行为外,一切都完美无缺。

UISearchController 处于活动状态时,customTableViewCell 的按钮会正常工作。如果我在 fetchedResultsController 显示其结果时单击同一个按钮,该方法认为索引 0 是发件人,无论我单击哪个按钮。

func playMP3File(sender: AnyObject) {

    if resultsSearchController.active {
        // ** THIS WORKS **
        // get a hold of my song
        // (self.filteredSounds is an Array)
        let soundToPlay = self.filteredSounds[sender.tag]
        // grab an attribute
        let soundFilename = soundToPlay.soundFilename as String
        // feed the attribute to an initializer of another class
        mp3Player = MP3Player(fileName: soundFilename)
        mp3Player.play()
    } else {

        // ** THIS ALWAYS GETS THE OBJECT AT INDEX 0 **
        let soundToPlay = fetchedResultsController.objectAtIndexPath(NSIndexPath(forRow: sender.tag, inSection: (view.superview?.tag)!)) as! Sound
        // OTHER THINGS I'VE TRIED
        // let soundToPlay = fetchedResultsController.objectAtIndexPath(NSIndexPath(forRow: sender.indexPath.row, inSection: (view.superview?.tag)!)) as! Sound
        // let soundToPlay: Sound = fetchedResultsController.objectAtIndexPath(NSIndexPath(index: sender.indexPath.row)) as! Sound
        let soundFilename = soundToPlay.soundFilename as String
        mp3Player = MP3Player(fileName: soundFilename)
        mp3Player.play()
    }
}

这是我的 cellForRowAtIndexPath 的缩略版,显示我正在设置单元格的按钮:

let customCell: SoundTableViewCell = tableView.dequeueReusableCellWithIdentifier("customCell", forIndexPath: indexPath) as! SoundTableViewCell

if resultsSearchController.active {
    let sound = soundArray[indexPath.row]
    customCell.playButton.tag = indexPath.row
} else {
    let sound = fetchedResultsController.objectAtIndexPath(indexPath) as! Sound
    customCell.playButton.tag = indexPath.row
}

    // add target actions for cells
    customCell.playButton.addTarget(self, action: "playMP3file:", forControlEvents: UIControlEvents.TouchUpInside)

我已经尝试了在这里找到的其他一些方法,例如将 CGPoints 翻译成 IndexPaths 等,但运气不佳。当我单击模拟器中的按钮时,编译器中看起来很有希望的一切都崩溃了。

感谢您的阅读。

更新 安装 Xcode 7.1,重新启动,清理缓存,删除派生数据,冷启动。

解决方案

标签在很多情况下都可以完成工作(例如在 Array 中获取位置)并在这里获得很多选票,但据我所知,它们并非始终有效.感谢 Mundi 为我指出更强大的解决方案。

// this gets the correct indexPath when resultsSearchController is not active
let button = sender as! UIButton
let view = button.superview
let cell = view?.superview as! SoundTableViewCell
let indexPath: NSIndexPath = self.tableView.indexPathForCell(cell)!
let soundToPlay = fetchedResultsController.objectAtIndexPath(indexPath) as! Sound

I've tried a few other approaches I've found here, such as translating CGPoints to IndexPaths, etc. without much luck.

翻译点确实是最稳健的解决方案。 This answer 包含正确的代码。