iOS分享扩展Team选择功能异常:点击选项后扩展闪退
解决iOS分享扩展中Team选择表格闪退的问题
嘿,我一眼就看出你遇到的闪退问题出在哪了——这是纯代码构建UITableView时非常容易踩的坑!
问题根源
当你的teamList有数据时,UITableView会尝试调用cellForRowAt方法去创建单元格,但你用了dequeueReusableCell(withIdentifier: "TeamCell", for: indexPath)来获取复用单元格,却没有提前给tableView注册这个标识符对应的cell类型,也没有在Storyboard/XIB里配置好带这个标识符的cell。这就导致系统找不到可复用的cell,直接崩溃闪退。而当teamList为空时,numberOfRowsInSection返回0,根本不会走到创建cell的逻辑,所以就不会闪退。
快速修复方案
你只需要在TeamTableViewController的viewDidLoad方法里,给tableView注册一下cell即可:
override func viewDidLoad() { super.viewDidLoad() self.clearsSelectionOnViewWillAppear = false // 注册默认的UITableViewCell,复用标识符为"TeamCell" tableView.register(UITableViewCell.self, forCellReuseIdentifier: "TeamCell") }
或者,如果你暂时不需要cell复用,也可以直接创建cell而不是复用:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // 直接初始化cell,不用复用 let cell = UITableViewCell(style: .default, reuseIdentifier: "TeamCell") cell.textLabel!.text = self.teamList[indexPath.item] return cell }
优化多选功能(额外建议)
既然你要实现多选团队的功能,这里给你补充一些关键的实现细节:
- 开启tableView的多选模式:
override func viewDidLoad() { super.viewDidLoad() // ... 其他代码 tableView.allowsMultipleSelection = true // 添加导航栏的"完成"按钮,用来确认选择 navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(doneTapped)) }
- 记录选中的团队,并更新cell的选中状态:
class TeamTableViewController: UITableViewController { var selectedTeams: [String] = [] // 存储选中的团队 // ... 其他代码 @objc func doneTapped() { // 将选中的团队传递回ShareViewController delegate?.sendingViewController(viewController: self, selectedTeams: selectedTeams) } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let team = teamList[indexPath.row] selectedTeams.append(team) tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark } override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { let team = teamList[indexPath.row] if let index = selectedTeams.firstIndex(of: team) { selectedTeams.remove(at: index) } tableView.cellForRow(at: indexPath)?.accessoryType = .none } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TeamCell", for: indexPath) cell.textLabel!.text = self.teamList[indexPath.item] // 恢复cell的选中状态 cell.accessoryType = selectedTeams.contains(teamList[indexPath.row]) ? .checkmark : .none return cell } }
- 更新协议和ShareViewController的接收逻辑:
// 修改协议 protocol TeamViewProtocol { func sendingViewController(viewController: TeamTableViewController, selectedTeams: [String]) } // ShareViewController里的方法 func sendingViewController(viewController: TeamTableViewController, selectedTeams: [String]) { self.item.value = selectedTeams.isEmpty ? "None" : selectedTeams.joined(separator: ", ") self.popConfigurationViewController() }
这样就能完整实现多选团队的功能啦!
内容的提问来源于stack exchange,提问作者Rasmus Puls
相关产品推荐
相关产品推荐

