如何实现UITableViewCell间的Segue跳转及条目独立数据存储
嘿,这个需求的核心是要搞定主条目和对应子数据的独立关联存储,我给你梳理一套落地的实现方案,分步骤来,不管是Swift还是OC都适用:
1. 先定义数据模型
首先得创建一个模型类,用来绑定每个主条目和它专属的子数据列表,这样每个主条目都有自己独立的子数据容器,不会串数据。
Swift版本
class MainItem: Codable { var title: String var subItems: [String] = [] init(title: String) { self.title = title } }
OC版本
@interface MainItem : NSObject @property (nonatomic, copy) NSString *title; @property (nonatomic, strong) NSMutableArray<NSString *> *subItems; @end @implementation MainItem - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; self.subItems = [NSMutableArray array]; } return self; } @end
2. 主列表ViewController(第一个VC)的实现
这里要维护一个MainItem数组作为数据源,处理主条目的添加、选中跳转的逻辑,关键是把选中的主条目传递给子VC。
Swift核心代码
class MainListVC: UIViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet weak var tableView: UITableView! // 主条目数据源,每个元素对应一个带独立子数据的条目 var mainItems: [MainItem] = [] override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self // 初始化默认测试数据,也可以让用户手动添加 mainItems.append(MainItem(title: "条目一")) mainItems.append(MainItem(title: "条目二")) } // 点击+按钮添加主条目 @IBAction func addMainItem(_ sender: UIBarButtonItem) { let alert = UIAlertController(title: "添加主条目", message: nil, preferredStyle: .alert) alert.addTextField { textField in textField.placeholder = "输入条目名称" } alert.addAction(UIAlertAction(title: "确定", style: .default) { [weak self] _ in guard let name = alert.textFields?.first?.text, !name.isEmpty else { return } self?.mainItems.append(MainItem(title: name)) self?.tableView.reloadData() }) present(alert, animated: true) } // UITableView数据源方法 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return mainItems.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "MainItemCell", for: indexPath) cell.textLabel?.text = mainItems[indexPath.row].title return cell } // 选中cell跳转,传递当前主条目 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) let selectedItem = mainItems[indexPath.row] performSegue(withIdentifier: "GoToSubList", sender: selectedItem) } // 准备Segue数据,把选中的主条目传给子VC override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "GoToSubList", let subVC = segue.destination as? SubListVC, let selectedItem = sender as? MainItem { subVC.currentMainItem = selectedItem } } }
3. 子列表ViewController(第二个VC)的实现
这里接收从主VC传过来的MainItem,直接用它的subItems作为子列表的数据源,添加子条目时直接修改这个数组,数据会自动和对应的主条目绑定。
Swift核心代码
class SubListVC: UIViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet weak var tableView: UITableView! // 接收主VC传递的当前主条目(必须在跳转前赋值) var currentMainItem: MainItem! override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self // 导航栏标题设为主条目名称,用户体验更好 title = currentMainItem.title } // 点击+按钮添加子条目 @IBAction func addSubItem(_ sender: UIBarButtonItem) { let alert = UIAlertController(title: "添加子条目", message: nil, preferredStyle: .alert) alert.addTextField { textField in textField.placeholder = "输入子条目内容" } alert.addAction(UIAlertAction(title: "确定", style: .default) { [weak self] _ in guard let content = alert.textFields?.first?.text, !content.isEmpty else { return } self?.currentMainItem.subItems.append(content) self?.tableView.reloadData() }) present(alert, animated: true) } // UITableView数据源方法 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return currentMainItem.subItems.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SubItemCell", for: indexPath) cell.textLabel?.text = currentMainItem.subItems[indexPath.row] return cell } }
4. 可选:持久化存储(重启APP不丢数据)
如果需要数据持久化,把mainItems数组存到本地就行,这里给个UserDefaults的简单实现(Swift版本):
在主VC的viewDidLoad里加载数据:
override func viewDidLoad() { super.viewDidLoad() // 加载本地存储的数据 if let data = UserDefaults.standard.data(forKey: "MainItems"), let savedItems = try? JSONDecoder().decode([MainItem].self, from: data) { mainItems = savedItems } else { // 初始化默认数据 mainItems.append(MainItem(title: "条目一")) mainItems.append(MainItem(title: "条目二")) } // ...其他初始化代码 }
在主VC的viewWillDisappear或者修改数据后保存:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 保存数据到本地 if let data = try? JSONEncoder().encode(mainItems) { UserDefaults.standard.set(data, forKey: "MainItems") } }
关键逻辑说明
- 每个主条目(比如“条目一”“条目二”)都是独立的
MainItem对象,自带subItems数组,所以它们的子数据完全隔离,不会互相干扰。 - 因为
MainItem是引用类型(Swift的class/OC的NSObject),子VC修改currentMainItem.subItems时,主VC的数据源也会同步更新,不用额外做回调。 - 这样点击“条目一”进去看到的是它自己的子数据,点击“条目二”进去就是空的,添加后只会存在“条目二”的子列表里,完全符合你的需求。
内容的提问来源于stack exchange,提问作者cicinho11
相关产品推荐
相关产品推荐

