Swift 3 - 重新排列并保留表格视图中的单元格

Posted

技术标签:

【中文标题】Swift 3 - 重新排列并保留表格视图中的单元格【英文标题】:Swift 3 - Rearrange and persist the cells in tableview 【发布时间】:2018-02-05 14:50:55 【问题描述】:

我有一个表格视图,我可以向其中添加项目,它会保存到核心数据,我也可以删除这些项目,一切正常

但是现在我想重新排列单元格并保留数据 目前我可以选择条形按钮编辑,它可以让我重新排列单元格,但是当我离开视图控制器时,它会重置为原来的样子

有人可以帮帮我吗?

class CustomWorkoutViewController: UIViewController 


@IBOutlet weak var newMusclesTableView: UITableView!

var workout:Workout?


override func viewDidLoad() 
    super.viewDidLoad()

    newMusclesTableView.delegate = self

    let nib = UINib(nibName: "muscleListTableViewCell", bundle: nil)
    newMusclesTableView.register(nib, forCellReuseIdentifier: "workCell")



override func viewDidAppear(_ animated: Bool) 
    self.newMusclesTableView.reloadData()




override func prepare(for segue: UIStoryboardSegue, sender: Any?) 

    if segue.identifier == "addMuscles"
        guard let destination = segue.destination as? AddMusclesViewController else 
            return
        
        destination.workout = workout

    

    else if segue.identifier == "addLogs"
        guard let destination = segue.destination as? WorkoutViewController,
            let selectedRow = self.newMusclesTableView.indexPathForSelectedRow?.row else 
                return
        
        destination.muscleLog = workout?.muscleList?[selectedRow]
    




func btnAction(_ sender: UIButton) 

    let point = sender.convert(CGPoint.zero, to: newMusclesTableView as UIView)
    let indexPath: IndexPath! = newMusclesTableView.indexPathForRow(at: point)

    let vc = viewMusclesViewController()
    let viewTitle = workout?.muscleList?[indexPath.row]

    vc.customInit(title: (viewTitle?.name)!)
    vc.titleStr = viewTitle?.name
    vc.gifStr = viewTitle?.muscleImage
    navigationController?.pushViewController(vc, animated: true)



@IBAction func editAction(_ sender: UIBarButtonItem) 

    self.newMusclesTableView.isEditing = !self.newMusclesTableView.isEditing
    sender.title = (self.newMusclesTableView.isEditing) ? "Done" : "Edit"




func deleteMuscle(at indexPath: IndexPath)
    guard let muscles = workout?.muscleList?[indexPath.row],
        let managedContext = muscles.managedObjectContext else
            return
    
    managedContext.delete(muscles)

    do
        try managedContext.save()

        newMusclesTableView.deleteRows(at: [indexPath], with: .automatic)
    catch
        print("Could not save")
        newMusclesTableView.reloadRows(at: [indexPath], with: .automatic)
    




override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.



这是我的 tableview 扩展

extension CustomWorkoutViewController: UITableViewDelegate,UITableViewDataSource 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    return workout?.muscleList?.count ?? 0


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    return 70


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = newMusclesTableView.dequeueReusableCell(withIdentifier: "muscleCell", for: indexPath) as? muscleListTableViewCell

    cell?.cellView.layer.cornerRadius = (cell?.cellView.frame.height)! / 2


    if let muscles = workout?.muscleList?[indexPath.row]
        cell?.muscleTitle?.text = muscles.name
        cell?.myBtn.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)

    


    return cell!



func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
    if editingStyle == .delete
        deleteMuscle(at: indexPath)
    


func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool 
    return true


func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) 

//How to persist data here?




【问题讨论】:

【参考方案1】:

您的代码决定使用此代码为一行显示哪个项目:

if let muscles = workout?.muscleList?[indexPath.row]

行顺序将由muscleList 中的顺序决定。当您使用它的编辑模式时,表格视图可以重新排列单元格,但它无法保存新的顺序,因为它不知道如何更改muscleList 的顺序。您对tableView(_:moveRowAt:to:) 的实现需要根据表视图更新更改顺序。

如果muscleList 是有序关系,则更改顺序。如果它不是有序关系,那么您需要添加一个可用于对关系进行排序的属性——即使像 sortOrder 属性这样简单的东西也可以。

【讨论】:

【参考方案2】:

我设法找到了解决我自己问题的方法 如果有人需要帮助,我会在这里发布以供将来使用

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) 
    let muscle = workout?.muscleList?[sourceIndexPath.row]
    workout?.removeFromRawMuscles(at: sourceIndexPath.row)
    workout?.insertIntoRawMuscles(muscle!, at: destinationIndexPath.row)

    do
        try muscle?.managedObjectContext?.save()


    catch
        print("Rows could not be saved")
    

【讨论】:

这就是我所说的。 :)

以上是关于Swift 3 - 重新排列并保留表格视图中的单元格的主要内容,如果未能解决你的问题,请参考以下文章

在运行时重新排列表格视图中的单元格

如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift

滚动表格视图时单元格变为空白(swift)

重新排列表格视图单元格后如何更新核心数据记录

如何重新排列 UILocalNotification 表格视图的单元格?

保存、保留和检索数组中的选定单元格