Reputation: 119
I'm using UITableView for showing banners which shows image and title.
The youtube link shows the animation of filtering banners. When I press "fav" button, it does not animate smoothly. I'd like to have the animation smooth.
This is my swift code of UITableView
.
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredTournamentlist.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "entryCell", for: indexPath) as? TournamentEntryCell {
cell.usernameLabel.text = filteredTournamentlist[indexPath.row].master_info.name
cell.titleTabel.text = self.filteredTournamentlist[indexPath.row].name
cell.dateLabel.text = DatetimeHelper.StringFromString(
string: self.filteredTournamentlist[indexPath.row].eventDate,
fromFormat: DatetimeHelper.DBDateFormat,
toFormat: DatetimeHelper.JPStringFormat
)
cell.gameInfoLabel.text = self.filteredTournamentlist[indexPath.row].gameName
self.tournamentModel.getThumbnail(path: self.filteredTournamentlist[indexPath.row].thumbnail_path) { image in
cell.thumbnailView.image = image
}
self.profileInfoModel.getIcon(path: self.filteredTournamentlist[indexPath.row].master_info.icon_path) { icon in
cell.iconView.image = icon
}
let selectedView = UIView()
selectedView.backgroundColor = Colors.plain
cell.selectedBackgroundView = selectedView
return cell
}
return UITableViewCell()
}
}
It just sets some information around banner. And this↓ is a code of collectionview which shows filter buttons such as "fav" and "plan".
extension HomeViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "buttonCell", for: indexPath) as! PlainSquareButtonCollectionViewCell
cell.button.setTitle(fileterButtonLabels[indexPath.row], for: .normal)
let input = HomeViewModel.Input(
getHomeTournamentsTrigger: Driver.never(),
getUserInfo: Driver.never(),
filter: cell.button.rx.tap
.map { [unowned self] in
return self.fileterButtonLabels[indexPath.row]
}
.asDriverOnErrorJustComplete(),
down: cell.rx.downButton
.map { b in
return b
}.asDriverOnErrorJustComplete()
)
let output = homeViewModel.transform(input: input)
output.filteredTournamentList
.drive(onNext: { [unowned self] tournamentList in
self.filteredTournamentlist = tournamentList
self.cardTableView.reloadData()
})
.disposed(by: disposeBag)
return cell
}
}
The tableView shows every information in filteredTournamentlist
, and the content of filteredTournamentlist
is changed by the filter buttons.
I don't know how to make the animation smooth... Help me!
Upvotes: 1
Views: 63
Reputation: 5660
.drive(onNext: { [unowned self] tournamentList in
self.filteredTournamentlist = tournamentList
self.cardTableView.reloadData() // <<--------- RELOAD DATA
})
Calling reloadData()
will not give you the expected animation. What ever changes are going to happen when you tap on fav
button you need to first determine and then you can apply those changes inside beginUpdates()
& endUpdates()
block.
It seems you have single section in the table view showing items, if so then it will be simpler for me to explain how to achieve the table view reload animation.
fav
or plan
button from your data source.IndexPath
s which are going to be changed (reload, add, delete).Apply the change inside cardTableView.beginUpdates()
& cardTableView.endUpdates()
.
Here is sample code for that
// ONLY CONSIDERING SINGLE SECTION, CALCULTION WILL BE COMPLEX FOR MULTI SECTION TABLEVIEW
// 1. Calculation of IndexPaths which are going to be impacted
let oldCellCount = dataSource.numberOfRowsInSection(0) // Get cell count before change
let newCellCount = dataSource.numberOfRowsInSection(0) // Get cell count after the change
var indexPathsToReload: [IndexPath] = []
var indexPathsToInsert: [IndexPath] = []
var indexPathsToDelete: [IndexPath] = []
if oldCellCount > newCellCount {
// Need to delete and reload few cells
indexPathsToReload = (0..<newCellCount).map { IndexPath(row: $0, section: 0) }
indexPathsToDelete = (newCellCount..<oldCellCount).map { IndexPath(row: $0, section: 0) }
} else if oldCellCount < newCellCount {
// Need to add and reload few cells
indexPathsToReload = (0..<oldCellCount).map { IndexPath(row: $0, section: 0) }
indexPathsToInsert = (oldCellCount..<newCellCount).map { IndexPath(row: $0, section: 0) }
} else {
// No change in cell count
indexPathsToReload = (0..<newCellCount).map { IndexPath(row: $0, section: 0)}
}
// 2. Reload with animation
tableView.beginUpdates()
tableView.deleteRows(at: indexPathsToDelete, with: .none) <<--- Use your expected animation here `fade`, `right`, `top`, `left` & more
tableView.reloadRows(at: indexPathsToReload, with: .none)
tableView.insertRows(at: indexPathsToInsert, with: .none)
tableView.endUpdates()
Upvotes: 2