基于RxSwift的TableView自定义滑动收藏动作:如何获取行数据?
问题:RxSwift中TableView侧滑收藏如何获取对应行数据?
现有代码实现
ViewModel中的news变量
var news = PublishSubject<[Article]>()
HomeViewController的RxSwift扩展
extension HomeViewController { func designTableView() { newsTable.separatorStyle = .none newsTable.showsVerticalScrollIndicator = false } func createCellView() { homeViewModel.news.bind(to: newsTable.rx.items(cellIdentifier: "cell", cellType: NewsCell.self)) { _, news, cell in cell.newsTitle.text = news.title cell.newsImage?.sd_setImage(with: URL(string: news.urlToImage ?? ""), placeholderImage: UIImage(systemName: "photo")) }.disposed(by: disposeBag) } func whenNewsSelected() { newsTable.rx.modelSelected(Article.self).bind { article in let vc = self.storyboard?.instantiateViewController(withIdentifier: "NewsDetail") as? NewsDetails vc?.article = article self.navigationController?.pushViewController(vc!, animated: true) }.disposed(by: disposeBag) } func setDelegateForTableView() { newsTable.rx.setDelegate(self).disposed(by: disposeBag) } }
遇到的问题
我想给Cell添加收藏动作,已经写了侧滑操作的代码,但不知道怎么获取当前行对应的新闻数据:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let FlagAction = UIContextualAction(style: .normal, title: "Fav", handler: { (_: UIContextualAction, _: UIView, success: (Bool) -> Void) in print("osman") success(true) }) FlagAction.backgroundColor = .orange return UISwipeActionsConfiguration(actions: [FlagAction]) }
解决方案
方式一:利用RxSwift内置的model(at:)方法
RxSwift的TableView扩展提供了直接通过indexPath获取对应模型的方法,在侧滑的handler里这样用:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let flagAction = UIContextualAction(style: .normal, title: "Fav", handler: { [weak self] (_, _, success) in guard let self = self else { success(false) return } // 获取对应行的Article模型 guard let article = try? tableView.rx.model(at: indexPath) as Article else { success(false) return } // 这里写你的收藏逻辑,比如存到本地数据库或者调用收藏API print("收藏文章:\(article.title ?? "无标题")") success(true) }) flagAction.backgroundColor = .orange return UISwipeActionsConfiguration(actions: [flagAction]) }
注意加上[weak self]避免循环引用,用try?处理可能的索引越界等错误情况。
方式二:在ViewModel中维护数据源数组
如果希望更直接地访问数据,可以在ViewModel里额外维护一个当前显示的数组,同步更新:
// ViewModel中添加 var currentArticles: [Article] = [] // 假设你有获取新闻的方法,更新数据时同步赋值 func fetchNews() { // 模拟获取到新闻数据 let fetchedArticles: [Article] = ... currentArticles = fetchedArticles news.onNext(fetchedArticles) }
然后在侧滑方法里直接通过indexPath访问:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let flagAction = UIContextualAction(style: .normal, title: "Fav", handler: { [weak self] (_, _, success) in guard let self = self, indexPath.row < self.homeViewModel.currentArticles.count else { success(false) return } let article = self.homeViewModel.currentArticles[indexPath.row] // 处理收藏逻辑 print("收藏文章:\(article.title ?? "无标题")") success(true) }) flagAction.backgroundColor = .orange return UISwipeActionsConfiguration(actions: [flagAction]) }
内容的提问来源于stack exchange,提问作者themmfa
相关产品推荐
相关产品推荐

