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

Swift:通过侧边菜单切换时保留已实例化的视图控制器

复用已实例化的视图控制器实现侧边菜单跳转

嘿,这个需求太常见了——每次点击菜单都重新创建控制器不仅浪费资源,还可能丢失之前的页面状态,用缓存已实例化的控制器就能完美解决。我给你整理了一套可直接复用的实现方案:

核心思路

用一个容器(数组/字典)存储已经创建过的控制器实例,每次点击菜单时先检查缓存:

  • 如果缓存里有对应的控制器,直接复用
  • 如果没有,创建新实例并存入缓存,再进行跳转

具体代码实现

1. 声明缓存容器

在你的侧边菜单控制器(UITableViewController子类)里,添加一个私有数组用来缓存控制器:

private var viewControllerCache: [UIViewController?] = []

2. 初始化缓存占位

在viewDidLoad里根据你的菜单选项数量初始化缓存数组(用nil占位,后续创建后替换):

override func viewDidLoad() {
    super.viewDidLoad()
    // 这里的3替换成你侧边菜单的选项总数
    viewControllerCache = Array(repeating: nil, count: 3)
}

3. 修改单元格点击事件

更新tableView(_:didSelectRowAt:)方法,加入缓存判断逻辑:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.tableView.deselectRow(at: indexPath, animated: true)
    
    // 先从缓存中获取目标控制器
    var targetVC: UIViewController? = viewControllerCache[indexPath.row]
    
    // 缓存为空时,创建新实例并缓存
    if targetVC == nil {
        switch indexPath.row {
        case 0:
            targetVC = LaunchViewController() // 替换成你的第一个控制器类
            targetVC?.title = "启动页"
        case 1:
            targetVC = SettingsViewController() // 第二个控制器
            targetVC?.title = "设置"
        case 2:
            targetVC = ProfileViewController() // 第三个控制器
            targetVC?.title = "个人中心"
        // 按需添加更多菜单选项的case
        default:
            return
        }
        // 将新创建的控制器存入缓存
        viewControllerCache[indexPath.row] = targetVC
    }
    
    // 确保控制器存在,推入导航栈(避免重复push同一控制器)
    if let vc = targetVC, navigationController?.topViewController !== vc {
        navigationController?.pushViewController(vc, animated: true)
    }
}

额外优化建议

  • 如果你的菜单选项是动态生成的(比如从服务器获取),可以用字典替代数组,以控制器的唯一标识(比如类型名、自定义ID)作为key,这样更灵活。
  • 如果控制器需要接收动态参数,记得在第一次创建时传入;后续复用若需要更新参数,可以在push前重新设置控制器的属性。
  • 若控制器占用内存较大,可在didReceiveMemoryWarning方法中清理不常用的缓存实例,避免内存泄漏:
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // 清理所有缓存(或按需清理特定索引的缓存)
    viewControllerCache = Array(repeating: nil, count: viewControllerCache.count)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:27:20