如何通过自定义SegmentControllerCell控制UITableView单元格切换
实现SegmentedControl切换UITableView下方单元格
需求:在ViewController的UITableView中使用自定义SegmentControllerCell,点击分段控件的标签时,显示其下方对应的不同UITableViewCell。
现有代码
自定义SegmentControllerCell类
protocol SegmentControllerCellDelegate: AnyObject { func manageSegmentControl(cell: SegmentControllerCell) } class SegmentControllerCell: UITableViewCell, ReusableView, NibLoadableView { @IBOutlet weak var segmentController: UISegmentedControl! weak var delegate: SegmentControllerCellDelegate? override func awakeFromNib() { super.awakeFromNib() setupUI() } @IBAction func tappedSegmentControll(_ sender: UISegmentedControl) { self.delegate?.manageSegmentControl(cell: self ) } }
ViewController相关代码
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { switch BrandSection(rawValue: indexPath.section)! { case .profile: guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: BrandTableViewCell.self), for: indexPath) as? BrandTableViewCell else { return UITableViewCell() } cell.cellType = .brandPage return cell case .segment: guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SegmentControllerCell.self), for: indexPath) as? SegmentControllerCell else { return UITableViewCell() } cell.delegate = self return cell case .products: guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: BrandProductionsCell.self), for: indexPath) as? BrandProductionsCell else { return UITableViewCell() } return cell } } extension BrandProfileVC: SegmentControllerCellDelegate { func manageSegmentControl(cell: SegmentControllerCell) { if cell.segmentController.selectedSegmentIndex == 0 { self.brandTableView.reloadData() print("index 0") } else if cell.segmentController.selectedSegmentIndex == 1 { self.brandTableView.reloadData() print("index 1") } } }
解决方案
要实现点击分段切换下方单元格,需要添加状态记录并调整表格数据源逻辑:
- 添加状态变量
在BrandProfileVC中添加变量保存当前选中的分段索引:
private var selectedSegmentIndex = 0
- 更新代理方法
修改manageSegmentControl方法,更新状态变量后再刷新表格:
func manageSegmentControl(cell: SegmentControllerCell) { selectedSegmentIndex = cell.segmentController.selectedSegmentIndex brandTableView.reloadData() }
- 保持Segment选中状态
表格刷新后,分段控件的选中状态会被重置,所以在cellForRowAt的.segment分支中恢复选中状态:
case .segment: guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SegmentControllerCell.self), for: indexPath) as? SegmentControllerCell else { return UITableViewCell() } cell.delegate = self cell.segmentController.selectedSegmentIndex = selectedSegmentIndex return cell
- 根据选中索引切换单元格
在.products分支中,根据selectedSegmentIndex返回不同的单元格:
case .products: if selectedSegmentIndex == 0 { // 返回索引0对应的单元格 guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: BrandProductionsCell.self), for: indexPath) as? BrandProductionsCell else { return UITableViewCell() } // 配置该单元格的数据 return cell } else { // 返回索引1对应的单元格 guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: OtherProductCell.self), for: indexPath) as? OtherProductCell else { return UITableViewCell() } // 配置该单元格的数据 return cell }
- (可选)调整行数
如果不同分段对应的下方单元格数量不同,修改numberOfRowsInSection方法:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch BrandSection(rawValue: section)! { case .profile: return 1 case .segment: return 1 case .products: // 根据选中分段返回对应行数 return selectedSegmentIndex == 0 ? 5 : 3 } }
内容的提问来源于stack exchange,提问作者Bedri Doğan
相关产品推荐
相关产品推荐

