iOS UITableView move Cells in Code

10,057

Solution 1

This code works, but it only example. adapt it for you. create new file and put this code in it, build it and check.

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!


    var scores = ["1", "2", "3", "4", "5"]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func move(from: IndexPath, to: IndexPath) {
        UIView.animate(withDuration: 1, animations: {
            self.tableView.moveRow(at: from, to: to)
        }) { (true) in
            // write here code to remove score from array at position "at" and insert at position "to" and after reloadData()
        }
    }

    @IBAction func buttonPressed(_ sender: UIButton) {
        let fromIndexPath = IndexPath(row: 4, section: 0)
        let toIndexPath = IndexPath(row: 1, section: 0)
        move(from: fromIndexPath, to: toIndexPath)
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return scores.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? TableViewCell
        if let cell = cell {
            cell.setText(text: scores[indexPath.row])
        }
        return cell ?? UITableViewCell()
    }

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

}   

For correctly use, you need to insert new element in array at last, reload data and after you can call method move() and put in it current indexPath and indexPath to insert you need.

Solution 2

Try this code for move row Up/Down

var longPress = UILongPressGestureRecognizer (target: self, action:#selector(self.longPressGestureRecognized(_:)))                 
ToDoTableView.addGestureRecognizer(longPress)

//MARK: -longPressGestureRecognized

 func longPressGestureRecognized(_ gestureRecognizer: UIGestureRecognizer) {

    let longPress = gestureRecognizer as! UILongPressGestureRecognizer
    let state = longPress.state
    let locationInView = longPress.location(in: ToDoTableView)
    let indexPath = ToDoTableView.indexPathForRow(at: locationInView)

    struct Path {
        static var initialIndexPath : IndexPath? = nil
    }

    switch state {
    case UIGestureRecognizerState.began:
        if indexPath != nil {
            let cell = ToDoTableView.cellForRow(at: indexPath!) as UITableViewCell!
            UIView.animate(withDuration: 0.25, animations: { () -> Void in
                cell?.alpha = 0.0
            }, completion: { (finished) -> Void in
                if finished {
                    UIView.animate(withDuration: 0.25, animations: { () -> Void in
                        cell?.alpha = 1
                    })
                } else {
                    cell?.isHidden = true
                }
            })
        }
    case UIGestureRecognizerState.changed:

        if ((indexPath != nil) && (indexPath != Path.initialIndexPath)) {
            itemsArray.insert(itemsArray.remove(at: Path.initialIndexPath!.row), at: indexPath!.row)
            ToDoTableView.moveRow(at: Path.initialIndexPath!, to: indexPath!)
            Path.initialIndexPath = indexPath
        }
    default:
        print("default:")
    }
}
Share:
10,057

Related videos on Youtube

Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I recently started working on a small iOS Project where I have a Game Score Leaderboard represented by a UITableView, whenever the Player gets a new Highscore the Leaderboard gets visible and his Score Entry (Including Picture, Name and Score) represented by a UITableViewCell is supposed to move to the new right Spot in the TableView Leaderboard it now belongs to. The calculation of the new index is working fine but the cell is not moving at all.

    Some info:

    • The Leaderboard is populated succesful,

    • I set the func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool to true

    • Also implemented the func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)

    correctly.

    I am thinking that maybe I am missing something but the problem could also lie somewhere else, I don't know and would really appreciate some help.

    Delegate Mehods for Editing

    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    // Handles reordering of Cells
    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        let player = players[sourceIndexPath.row]
        players.remove(at: sourceIndexPath.row)
        players.insert(player, at: destinationIndexPath.row)
    }
    

    Code where I try to move Row

    func newHighscore(highscore: Int) {
        friendsTableView.reloadData()
        let myNewIndex = Player.recalculateMyIndex(players: players, score: highscore)
        friendsTableView.moveRow(at: [0,Player.myIndex], to: [0,myNewIndex])
    
    }
    
    • Vasilis D.
      Vasilis D. about 6 years
      After you update your new data source for example the array of objects that have the score , name etc and you have placed your new score to the right place on the data source you should call the method self.myTableViewName.reloadData() and it will redraw the tableview
    • Cesare
      Cesare about 6 years
      Use insertRow to move cells around
    • Admin
      Admin about 6 years
      @ΒασίληςΔ. Will it then Animate this movement like it would when dragged in editing mode?
    • Admin
      Admin about 6 years
      @Cesare but that inserts cells which I don’t Wanna do, I want to move them what else should the move at: to: function be about when its not moving rows from A to B
    • Sergey Hleb
      Sergey Hleb about 6 years
      It's so hard, maybe better to use array's updating and after that use reloadData() ???
    • Admin
      Admin about 6 years
      Why should it be hard?
    • Sergey Hleb
      Sergey Hleb about 6 years
      update array and reload data more easlier
    • Admin
      Admin about 6 years
      @SergeyHleb but then it’s much harder to show an animation where the cell moves up and all others move down
    • Sergey Hleb
      Sergey Hleb about 6 years
      if you want to animate this, yes, you need to use this methods
    • Admin
      Admin about 6 years
      Okay I need to use the move at:,to: method but what is supposed to be so hard about it, I used it as described in the Dev Reference but it is not working are there any special optional delegate functions I need to implement anything I need to call before the move function,...
    • Sergey Hleb
      Sergey Hleb about 6 years
      add chunk of your code with this delegates methods to your question
    • Sergey Hleb
      Sergey Hleb about 6 years
      and code where you implement new cell with score and tries to move it
    • Admin
      Admin about 6 years
      Alright just did that, I am glad for your help @SergeyHleb
    • Sergey Hleb
      Sergey Hleb about 6 years
      before your newHighscore() you doing update of array. and new highscore appears in it at last position?
    • Admin
      Admin about 6 years
      Do you mean reloadData, yes I did this to show the updated data instantly, this function is used to reload the whole tree which I dont need, i just need to change one rows position
    • Sergey Hleb
      Sergey Hleb about 6 years
      I write code for you yet, in few minutes answer can be
    • Admin
      Admin about 6 years
      Thanks a lot @SergeyHleb
    • Sergey Hleb
      Sergey Hleb about 6 years
      add it. insert it in new project, build and check. if you press button, cell moves to new position
  • Admin
    Admin about 6 years
    But I dont need a gesture recognizer I want the cell to be animated automatically and not like in Edit Mode by the user itself as I understood this is simple done by the move function I dont understand why I should overcomplicate things when Apple already provides the methods I need. Can please somebody help me out?
  • AtulParmar
    AtulParmar about 6 years
  • Admin
    Admin about 6 years
    Okay when I now tried to use your example on my Project it didnt work, even I did not miss anything which means I added something that prevents it from happening
  • Sergey Hleb
    Sergey Hleb about 6 years
    did you delete delegate methods, which don't used in my example? i can describe all steps if you need
  • Admin
    Admin about 6 years
    Okay I finally figured it out, I don’t know why but when I call the UITableView.reloadData() shortly before the move function it does not work that was the problem
  • Admin
    Admin about 6 years
    Okay this was just one of a few problems My View Controller a Child Controller of a Page View Controller and whenever I setViewController I call the move Table View Function you Write which does not work in this specific case. Any Ideas? Thanks so far though helped a lot already
  • Admin
    Admin about 6 years
    It works though if I call it via Button Action so if you would write all the steps down it would not help since your code works
  • Sergey Hleb
    Sergey Hleb about 6 years
    i don't see your code, and it's problem. are you have a telegram account?
  • Admin
    Admin about 6 years
    Yes we should transfer the communication to Telegram
  • Sergey Hleb
    Sergey Hleb about 6 years
    write to me how can I find you
  • Admin
    Admin about 6 years
    My username is: TheRealSirJoe
  • Fa.Shapouri
    Fa.Shapouri over 2 years
    this code is really nice when reorder by user is needed