gpt4 book ai didi

ios - Swift UITableView 删除所选行及其上方的任何行

转载 作者:搜寻专家 更新时间:2023-11-01 05:50:26 24 4
gpt4 key购买 nike

我的 TableView 包含表示里程日志的单元格。我需要允许用户删除任何错误的能力。 TableView 按降序列出日志。删除顶行就可以了。删除任何其他行我需要发出警告作为警报,如果确认则删除所选行及其上方的所有行。这可能吗?任何地方都有示例代码吗?

更新

根据到目前为止我得到的两个答案,我做了以下......

import UIKit
import CoreData

class MileageLogsTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {

@IBOutlet var milageLogTableView: UITableView!

override func viewDidLoad() {
super.viewDidLoad()

do {
try fetchedResultsController.performFetch()
} catch {
let fetchError = error as NSError
print("Unable to fetch MileageLog")
print("\(fetchError), \(fetchError.localizedDescription)")
}

// Display an Edit button in the navigation bar for this view controller.
self.navigationItem.leftBarButtonItem = self.editButtonItem()
}

// MARK: - Table view data source

private lazy var fetchedResultsController: NSFetchedResultsController = {
// Initialize Fetch Request
let fetchRequest = NSFetchRequest(entityName: "MileageLog")

// Add Sort Descriptors
let dateSort = NSSortDescriptor(key: "tripDate", ascending: false)
let mileSort = NSSortDescriptor(key: "startMileage", ascending: false)
fetchRequest.sortDescriptors = [dateSort, mileSort]

let delegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedObjectContext = delegate.managedObjectContext

// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: "rootCache")

//ADDED AS PER ANSWER FROM SANDEEP
fetchedResultsController.delegate = self

return fetchedResultsController

}()


override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if let sections = fetchedResultsController.sections {
return sections.count
}

return 0
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let sections = fetchedResultsController.sections {
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}

return 0
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier("MileageLogCell") as! MileageTableViewCell

// Fetch MileageLog
if let mileageLog = fetchedResultsController.objectAtIndexPath(indexPath) as? MileageLog {
//format date as medium style date
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
let logDateString = formatter.stringFromDate(mileageLog.tripDate!)
//format NSNumber mileage to string
let mileageInt:NSNumber = mileageLog.startMileage!
let mileageString = String(mileageInt)

cell.lb_LogDate.text = logDateString
cell.lb_LogMileage.text = mileageString
cell.lb_LogStartLocation.text = mileageLog.startLocation
cell.lb_LogDestination.text = mileageLog.endLocation
}
return cell
}


// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}

// MARK: Fetched Results Controller Delegate Methods
func controllerWillChangeContent(fetchedResultsController: NSFetchedResultsController) {
tableView.beginUpdates()
}

func controllerDidChangeContent(fetchedResultsController: NSFetchedResultsController) {
tableView.endUpdates()
}

func controller(fetchedResultsController: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch (type) {
case .Insert:
break;
case .Delete:

let context = fetchedResultsController.managedObjectContext
if let indexPath = indexPath {

if indexPath.row == 0 {
//this is the top (first row)
// Deleting without warning
let objectToDelete = fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject
context.deleteObject(objectToDelete)

do {
try context.save()
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

} catch {
print(error)
}
self.tableView.reloadData();

} else {
//we are deleted a row that is not the top row
// we need to give a warning and if acknowledged then delele all rows from the selected row and all rows above it

let alertController = UIAlertController(title: nil, message: "Are you sure? This will remove this and all logs above it.", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in

}
alertController.addAction(cancelAction)
let deleteAction = UIAlertAction(title: "Delete", style: .Default) { (action) in

for deleteindex in 0 ... indexPath.row {
let deleteIndexPath = NSIndexPath(forRow: deleteindex, inSection: 0)
let objectToDelete = self.fetchedResultsController.objectAtIndexPath(deleteIndexPath) as! NSManagedObject
context.deleteObject(objectToDelete)

do {
try context.save()
self.tableView.deleteRowsAtIndexPaths([deleteIndexPath], withRowAnimation: .Fade)

} catch {
print(error)
}
}
self.tableView.reloadData();
}
alertController.addAction(deleteAction)

// Dispatch on the main thread
dispatch_async(dispatch_get_main_queue()) {
self.presentViewController(alertController, animated: true, completion:nil)
}

}
}
break;
case .Update:
break;
case .Move:
break;
}
}

}

现在我的问题是触摸 Delete 没有任何作用。 TreeView 已正确填充。编辑按钮位于导航栏中。单击“编辑”,每行上都会出现“无条目”图标...滑动一行,就会出现“删除” block 。单击删除,什么也没有...!我错过了什么?

最终工作修复

// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {

switch editingStyle {

case .Delete:
let context = fetchedResultsController.managedObjectContext
if indexPath.row == 0 {
//this is the top (first row)
// Deleting without warning
let indexPathToDelete = NSIndexPath(forRow: 0, inSection: 0)
let objectToDelete = fetchedResultsController.objectAtIndexPath(indexPathToDelete) as! NSManagedObject
context.deleteObject(objectToDelete)

do {
try context.save()
//self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

} catch {
print(error)
}
//self.tableView.reloadData();

} else {
//we are deleted a row that is not the top row
// we need to give a warning and if acknowledged then delele all rows from the selected row and all rows above it

let alertController = UIAlertController(title: nil, message: "Are you sure? This will remove this and all logs above it.", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in

}
alertController.addAction(cancelAction)
let deleteAction = UIAlertAction(title: "Delete", style: .Default) { (action) in

for deleteindex in 0 ... indexPath.row {
let deleteIndexPath = NSIndexPath(forRow: deleteindex, inSection: 0)
let objectToDelete = self.fetchedResultsController.objectAtIndexPath(deleteIndexPath) as! NSManagedObject
context.deleteObject(objectToDelete)

}

do {
try context.save()

} catch {
print(error)
}
}
alertController.addAction(deleteAction)

// Dispatch on the main thread
dispatch_async(dispatch_get_main_queue()) {
self.presentViewController(alertController, animated: true, completion:nil)
}

}
break;

default :
return
}

}

// MARK: Fetched Results Controller Delegate Methods
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
break;
case .Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
break;
case .Move:
break;
}
}

最佳答案

除了使用编辑操作的增强功能之外,这是一个简单的解决方案。

首先不要触摸委托(delegate)方法didChangeObject
保持原状。它在托管对象上下文中进行更改后调用,其工作方式类似于 MVC 模式中的 View 。

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
self.configureCell(tableView.cellForRow(at: indexPath!)!, atIndexPath: indexPath!)
case .move:
tableView.deleteRows(at: [indexPath!], with: .fade)
tableView.insertRows(at: [newIndexPath!], with: .fade)
}
}

插入代码以删除 commitEditingStyle 中的行,其工作方式类似于 MVC 模式中的模型。该代码删除当前部分上方选定行的所有行。

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
switch editingStyle {
case .delete:
let context = fetchedResultsController.managedObjectContext
let section = indexPath.section
let currentRow = indexPath.row
for index in 0...currentRow {
let indexPathToDelete = IndexPath(row: index, section: section)
let objectToDelete = fetchedResultsController.object(at: indexPathToDelete) as! NSManagedObject
context.delete(objectToDelete)
}
do {
try context.save()
} catch {
print(error)
}

case .insert, .none: break
}
}

关于ios - Swift UITableView 删除所选行及其上方的任何行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36861431/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com