我有一個不穩定的問題,我正在開發一個應用程序。我有一個顯示在表格視圖中的曲目數組。在此表格視圖中,用戶可以向左滑動單個曲目,並出現包含三個項目的菜單。其中之一是刪除操作。這是這個行動,我有一個問題。與tableView.deleteRows崩潰(在:),與:)
該菜單中的UITableViewDelegate方法來實現:
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
檢索到選定的行用以下語句:
selectedTrack = indexPath.row
然後我就與這個片段刪除操作:
//Delete the selected track
let deleteAction = UITableViewRowAction(style: .default, title: deleteTitle) { (action, indexPath) -> Void in
if self.savedTracks.count > 0 {
self.newTrack = self.savedTracks[self.selectedTrack]
let albumName = (self.newTrack?.trackName)! + String(describing: (self.newTrack?.trackDate)!)
self.savedTracks.remove(at: self.selectedTrack)
self.trackOverviewTable.deleteRows(at: [indexPath], with: .fade)
self.photoStore.deleteAlbumFromDeletedTrack(with: albumName)
self.trackOverviewTable.reloadData()
self.saveTracksToDisk()
} else {
self.trackOverviewTable.reloadData()
}
該程序運行正常,但如果我刪除兩行接一行,th e程序崩潰時發表評論:libC++ abi.dylib:以NSException類型的未捕獲異常終止。
如果我註釋掉(或刪除)行:
self.trackOverviewTable.deleteRows(at: [indexPath], with: .fade)
該應用程序運行正常,但刪除行的動畫了。有趣的是,應用程序有時可以使用「deleteRows」函數正常運行,但通常不會。我看了幾個評論,但我還沒有找到正確的答案。
表沒有的部分,所以該數據源的方法:
numberOfSections(in: UITableView)
未實現。 任何人都可以幫助我在正確的方向嗎?
基於Vadian的意見,我試圖將代碼片斷更改爲:
然而,這仍使應用程序崩潰。
應用程序崩潰的問題是我使用了一種複雜而奇怪的方式填充表視圖,這使得應用程序期望不同數量的錶行,然後確實存在。現在工作的代碼如下所示:
/** This method provides the actions when the user swipes a row left. The method first checks what sort of track it is. If the track is an emptyTrack or
instructionTrack, there will be no action that can be chosen. When the track is a regular recorded track the method will provide the user with the option
to post the selected track or delete the track.
*/
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let faultTitle = NSLocalizedString("No tracks.", comment: "The message in the selection when there are no tracks.")
let postTitle = NSLocalizedString("Post track.", comment: "The message in the selection for posting the track on social media.")
let deleteTitle = NSLocalizedString("Delete.", comment: "The message in the selection for deleting the track.")
selectedTrack = indexPath.row
let selectedTrackName = self.savedTracks[selectedTrack].trackName
//When the user swiped the empty or instruction track, only provide the fault action.
guard (selectedTrackName != self.emptyString) && (selectedTrackName != self.instructionString) else {
//The user selected the empty or instruction track, the action cannot be executed.
let faultAction = UITableViewRowAction(style: .normal, title: faultTitle, handler: { (action, indexPath) -> Void in
self.trackOverviewTable.reloadData() //Simply reload the table view after the action button is hit.
})
self.trackOverviewTable.cellForRow(at: indexPath)?.isSelected = false
return [faultAction]
}
//The post action first checks whether the user had bought the fll version.
//If the full version is bought the action moves to the posting menu.
let postAction = UITableViewRowAction(style: .normal, title: postTitle) { (action, indexPath) -> Void in
//The message when the full version has not been bought
let alertTitle = NSLocalizedString("Upgrade @Tracker", comment: "The user doesn't have the full capabilities.")
let alertMessage = NSLocalizedString("Do you want to upgrade @Tracker to unlock all functionalities?", comment: "Ask the user to buy the functionalities.")
//The new track will now be set to be the selected track so it can be transfered to
//the posting view controller
self.newTrack = self.savedTracks[self.selectedTrack]
if FULL_FUNCTIONALITY == true {
self.performSegue(withIdentifier: "postTrack", sender: self)
} else {
//Allow the user to post the track if the full functionality is bought
self.alertMessage(title: alertTitle, message: alertMessage, action: "Buy")
}
}
//Delete the selected track
let deleteAction = UITableViewRowAction(style: .default, title: deleteTitle) { (action, indexPath) -> Void in
//First set the warning message when the user wants to delete the track.
let title = NSLocalizedString("Warning", comment: "Ask alert the user that he is going to delete the track.")
let message = NSLocalizedString("Are you sure you want to delete the track?", comment: "Ask the user if he's sure.")
let alertYes = NSLocalizedString("Yes", comment: "Ja")
let alertNo = NSLocalizedString("No", comment: "Nee")
let alertMessage = UIAlertController.init(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: alertYes, style: .default, handler: { (action) in
self.deleteTrackFromTable(at: indexPath)
var indexPathSelected = indexPath
indexPathSelected.row = 0
self.trackOverviewTable.scrollToRow(at: indexPathSelected, at: .none, animated: true)
self.presentingViewController?.dismiss(animated: true, completion: nil)
})
alertMessage.addAction(okAction)
let notOkAction = UIAlertAction(title: alertNo, style: .default, handler: { (action) in
self.trackOverviewTable.reloadData()
self.presentingViewController?.dismiss(animated: true, completion: nil)
})
alertMessage.addAction(notOkAction)
self.present(alertMessage, animated: true, completion: nil)
}
postAction.backgroundColor = MENU_COLOR_1
self.trackOverviewTable.cellForRow(at: indexPath)?.isSelected = false
return [deleteAction, postAction, analysisAction]
}
我在insertRows和deleteRows時處於相同的情況。 – BollMose
嗨BollMose,自從我實施了Vadian的建議以後,我再也沒有問題了。我稍後會發布代碼。 – MacUserT
有趣。我的應用程序在惰性行然後deleteRows時崩潰,但它只運行deleteRows。 – BollMose