【问题标题】:iOS UITableView move Cells in CodeiOS UITableView 在代码中移动单元格
【发布时间】:2018-03-29 11:22:30
【问题描述】:

我最近开始从事一个小型 iOS 项目,我有一个由 UITableView 表示的游戏得分排行榜,每当玩家获得新的高分时,排行榜就会可见,并且他的得分条目(包括图片、名称和得分) ) 由UITableViewCell 表示应该移动到它现在所属的TableView 排行榜中的新右侧位置。新的index 的计算工作正常,但cell 根本没有移动。

一些信息:

  • 排行榜填充成功,

  • 我将func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool 设置为true

  • 还实现了func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)

正确。

我在想,也许我遗漏了一些东西,但问题也可能出在其他地方,我不知道,非常感谢一些帮助。

编辑的委托方法

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)
}

我尝试移动行的代码

func newHighscore(highscore: Int) {
    friendsTableView.reloadData()
    let myNewIndex = Player.recalculateMyIndex(players: players, score: highscore)
    friendsTableView.moveRow(at: [0,Player.myIndex], to: [0,myNewIndex])

}

【问题讨论】:

  • 在你更新你的新数据源之后,例如具有分数、名称等的对象数组,并且你已经将你的新分数放在数据源上的正确位置,你应该调用方法 self. myTableViewName.reloadData() 它将重绘表格视图
  • 使用 insertRow 移动单元格
  • @ΒασίληςΔ。然后它会像在编辑模式下拖动时那样为这个动作设置动画吗?
  • @Cesare 但是插入了我不想做的单元格,我想移动它们还有什么应该移动的:to: 函数是关于当它不将行从 A 移动到 B 时跨度>
  • 太难了,使用数组更新可能更好,然后使用 reloadData() ???

标签: ios swift xcode uitableview


【解决方案1】:

此代码有效,但它只是示例。适应你。创建新文件并将此代码放入其中,构建并检查。

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
    }

}   

为了正确使用,你需要最后在数组中插入新元素,重新加载数据,然后你可以调用方法move()并将当前的indexPath和indexPath放入你需要的地方。

【讨论】:

  • 好的,当我现在尝试在我的项目中使用你的示例时它没有工作,即使我没有错过任何东西,这意味着我添加了一些防止它发生的东西
  • 您是否删除了我的示例中未使用的委托方法?如果您需要,我可以描述所有步骤
  • 好吧,我终于弄明白了,我不知道为什么,但是当我在移动函数前不久调用 UITableView.reloadData() 时,它不起作用,这就是问题
  • 好吧,这只是几个问题之一,我的视图控制器是页面视图控制器的子控制器,每当我 setViewController 时,我都会调用你编写的移动表视图函数,这在这种特定情况下不起作用。有任何想法吗?到目前为止,虽然已经帮助了很多,但谢谢
  • 如果我通过按钮操作调用它,它可以工作,所以如果你写下所有步骤,它不会有帮助,因为你的代码可以工作
【解决方案2】:

尝试使用此代码向上/向下移动行

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:")
    }
}

【讨论】:

  • 但我不需要手势识别器我希望单元格自动进行动画处理,而不是像用户自己在编辑模式下那样,因为我知道这很简单,由移动功能完成我不明白为什么我应该当 Apple 已经提供了我需要的方法时,事情就变得过于复杂了。有人能帮帮我吗?
  • 当需要用户重新订购时,这段代码非常好
猜你喜欢
  • 1970-01-01
  • 2013-04-17
  • 2013-07-07
  • 1970-01-01
  • 2023-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多