I'm making a Twitter clone app. If I press the like button on the posts in each cell, I want to reflect the number of likes to increase. Also, I want to make it reflect in the cell as soon as I delete or modify the post. There is also a video player in the cell like Twitter, but every time I press the like button, the ViewModel accepts again, which causes the video that was running to turn off. Please tell me the best way to implement the Like button...
Cell.swift
func bind(_ viewModel: PostItemViewModel) {
.....
likesLabel.text = String(viewModel.likes)
....
}
....
likesBtn.rx.tapGesture().when(.ended).mapToVoid().asSignalOnErrorJustComplete()
.emit(onNext: { [unowned self] in
delegate?.pressLikesBtn(tag)
}).disposed(by: disposeBag)
ViewController.swift
class PostsViewController: UIViewController {
private let pressLikesRelay = PublishRelay<Int>()
private let deleteRelay = PublishRelay<Int>()
private let disposeBag = DisposeBag()
var viewModel: PostsViewModel!
.......
.......
private func bindViewModel() {
assert(viewModel != nil)
let viewWillAppear = rx.viewWillAppear
.mapToVoid()
.asSignalOnErrorJustComplete()
let pull = timeLineTableView.refreshControl!.rx
.controlEvent(.valueChanged)
.asSignal()
let reachedBottom = timeLineTableView.rx.reachedBottom().asSignal()
let input = PostsViewModel.Input(fetchInitial: Signal.merge(viewWillAppear, pull), fetchNext: reachedBottom, likesTrigger: pressLikesRelay.asSignal(), deleteTrigger: deleteRelay.asSignal())
let output = viewModel.transform(input: input)
output.posts.drive(timeLineTableView.rx.items(cellIdentifier: PostTableViewCell.identifier, cellType: PostTableViewCell.self)) {
row, item, cell in
cell.delegate = self
cell.bind(item)
cell.tag = row
}.disposed(by: disposeBag)
}
extension PostsViewController: PostTableCellDelegate {
func pressLikesBtn(_ index: Int) {
pressRelay.accept(index)
}
func deletePost(_ index: Int) {
deleteRelay.accept(index)
}
}
ViewModel.swift
final class PostsViewModel: ViewModelType {
...
private let postsRelay = BehaviorRelay<[PostItemViewModel]>(value: [])
.....
func transform(input: Input) -> Output {
.......
input.likesTrigger.emit(onNext: { [unowned self] index in
var updated = self.postsRelay.value
updated[index].plusLikes()
self.postsRelay.accept(updated)
}).disposed(by: disposeBag)
input.deleteTrigger.emit(onNext: { [unowned self] index in
var deleted = self.postsRelay.value
deleted.remove(at: index)
self.postsRelay.accept(deleted)
}).disposed(by: disposeBag)
return Output(
...,
posts: postsRelay.asDriver(),
...)
}
}
PostItemViewModel.swift
public struct PostItemViewModel {
.....
var likes: Int
....
mutating func plusLikes() {
self.vote1 +=1
}
}