Skip to content
This repository has been archived by the owner on Nov 5, 2020. It is now read-only.

ContentOffset/ScrollView is jumping when expanding/collapsing cells #22

Open
gaborcsontos opened this issue Mar 4, 2018 · 6 comments
Open
Milestone

Comments

@gaborcsontos
Copy link

gaborcsontos commented Mar 4, 2018

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!

@okhanokbay
Copy link
Owner

Hi! I'm not able to reproduce this. Can it be caused by some "scroll-to-show-expanded-cell" code? Do you have an example project that reproduces this issue? @gaborcsontos

@okhanokbay okhanokbay added this to the 1.0.1 milestone Mar 8, 2018
@gaborcsontos
Copy link
Author

gaborcsontos commented Mar 8, 2018

I had this issue with the original code during the animation, when the cells were expanding/collapsing.
After added the code above, it solved the scroll jumping.

@okhanokbay
Copy link
Owner

Can you please tell if it happens in Customization Example or Basic Example or in both @gaborcsontos

@gaborcsontos
Copy link
Author

It happened in my project, not in the examples.

@okhanokbay
Copy link
Owner

Thanks! Will look into this soon.

@tatsuya0505
Copy link

@gaborcsontos
I also have this problem.
I solved by your opening.
Thank you!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants