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 包含正确的代码。
我在 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 包含正确的代码。