This repository was archived by the owner on Nov 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 53
This repository was archived by the owner on Nov 5, 2020. It is now read-only.
ContentOffset/ScrollView is jumping when expanding/collapsing cells #22
Copy link
Copy link
Open
Milestone
Description
Hi Guys.
Thanks for this awesome library, it saved my life.
Perhaps I met with an annoying bug.
When I collapsed/expanded a section, the tableview's contentoffset had a weird jumping.
After spent some hours of researching to solve this really annoying problem, I found out the best solution is to set an observer when the contentOffset is changing.
After implementing some properties and the observer, the jumping affect disappears.
fileprivate var isCellUpdateInProgress: Bool = false
fileprivate var lastScrollOffset: CGPoint!
open override var dataSource: UITableViewDataSource? {
get {
return super.dataSource
}
set(dataSource) {
guard let dataSource = dataSource else { return }
expyDataSource = dataSource as? ExpyTableViewDataSource
super.dataSource = self
self.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.new, context: nil)
}
}
private func startAnimating(_ tableView: ExpyTableView, with type: ExpyActionType, forSection section: Int) {
let headerCell = (self.cellForRow(at: IndexPath(row: 0, section: section)))
let headerCellConformant = headerCell as? ExpyTableViewHeaderCell
CATransaction.begin()
headerCell?.isUserInteractionEnabled = false
//Inform the delegates here.
headerCellConformant?.changeState((type == .expand ? .willExpand : .willCollapse), cellReuseStatus: false)
expyDelegate?.tableView?(tableView, expyState: (type == .expand ? .willExpand : .willCollapse), changeForSection: section)
CATransaction.setCompletionBlock { [weak self] () -> (Void) in
//Inform the delegates here.
headerCellConformant?.changeState((type == .expand ? .didExpand : .didCollapse), cellReuseStatus: false)
self?.expyDelegate?.tableView?(tableView, expyState: (type == .expand ? .didExpand : .didCollapse), changeForSection: section)
headerCell?.isUserInteractionEnabled = true
self?.isCellUpdateInProgress = false
}
isCellUpdateInProgress = true
lastScrollOffset = tableView.contentOffset
tableView.beginUpdates()
//Don't insert or delete anything if section has only 1 cell.
if let sectionRowCount = expyDataSource?.tableView(tableView, numberOfRowsInSection: section), sectionRowCount > 1 {
var indexesToProcess: [IndexPath] = []
//Start from 1, because 0 is the header cell.
for row in 1..<sectionRowCount {
indexesToProcess.append(IndexPath(row: row, section: section))
}
//Expand means inserting rows, collapse means deleting rows.
if type == .expand {
self.insertRows(at: indexesToProcess, with: expandingAnimation)
}else if type == .collapse {
self.deleteRows(at: indexesToProcess, with: collapsingAnimation)
}
}
tableView.endUpdates()
tableView.layer.removeAllAnimations()
self.setContentOffset(self.lastScrollOffset, animated: false)
CATransaction.commit()
}
override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "contentOffset" {
if isCellUpdateInProgress {
self.setContentOffset(self.lastScrollOffset, animated: false)
}
}
}
Hope it will help!
tatsuya0505tatsuya0505
Metadata
Metadata
Assignees
Labels
No labels