You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用UserDefaults重启App后将TableView最后点击单元格置于顶部

解决方案

首先你现有代码存在一个关键问题:仅通过moveRow修改了TableView的显示顺序,但没有同步更新数据源数组。这会导致重启App后,数据源回到初始状态,无法恢复上次的布局。先修正点击事件的代码,同步更新数据源:

假设你的数据源数组名为dataSourceArray(替换成你实际的数组名),修改didSelectRowAt方法:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // 1. 把点击的元素移到数据源数组开头
    let selectedItem = dataSourceArray.remove(at: indexPath.row)
    dataSourceArray.insert(selectedItem, at: 0)
    
    // 2. 存储原始选中行的索引
    UserDefaults.standard.set(indexPath.row, forKey: "celdaPulsada")
    // 可选:标记用户是否点击过单元格,避免首次启动触发不必要的操作
    UserDefaults.standard.set(true, forKey: "hasSelectedCell")
    
    // 3. 更新TableView的行位置
    tableView.beginUpdates()
    tableView.moveRow(at: indexPath, to: IndexPath(row: 0, section: 0))
    tableView.endUpdates()
}

接下来处理App重启后的恢复逻辑,在ViewController的viewDidAppear(_:)方法中执行(该方法确保TableView已完成布局,滚动操作更可靠):

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    // 检查用户是否点击过单元格
    let hasSelected = UserDefaults.standard.bool(forKey: "hasSelectedCell")
    guard hasSelected else {
        return
    }
    
    // 读取存储的选中行索引
    let savedRow = UserDefaults.standard.integer(forKey: "celdaPulsada")
    // 确保索引在数据源有效范围内,避免数组越界
    guard savedRow >= 0 && savedRow < dataSourceArray.count else {
        return
    }
    
    // 调整数据源,将对应元素移到开头
    let selectedItem = dataSourceArray.remove(at: savedRow)
    dataSourceArray.insert(selectedItem, at: 0)
    
    // 刷新TableView并滚动到顶部
    tableView.reloadData()
    tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
}

如果你的数据源是从本地/网络加载的,需要确保在数据源加载完成后再执行上述恢复逻辑。

内容的提问来源于stack exchange,提问作者Monrac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:20:40