Event Scrolling (Scrollviewdidscroll) Never Called - Swift 3

Event scrolling (scrollViewDidScroll) never called - Swift 3

You just have to add the delegate to your viewDidLoad() func:

override func viewDidLoad() {        
super.viewDidLoad()
//add this line
self.scrollView.delegate = self

}

My scrollViewDidScroll function is not receiving calls

Add the scrollview delegate. Whenever you implement a delegate method you need tell it what controller to use, usually it will be self. It's caught me out a few times.

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
scrollViewer.delegate = self
}

UITableViewController scrollViewDidScroll: not called during cell removal

Well, after reading your question a few times, it looks like our issues aren't the same.

I believe your issue is because scrollViewDidScroll: is not called during some animations. You should see this answer here, though unaccepted (maybe because they imply user interaction is the only way to trigger it), it also contains a path to this answer about getting scrolling events during automated animations which may be of help.

Swift UIScrollViewDelegate not triggers scrollViewDidScroll event

how about you assign the delegate this way?

    class NavigationScrollView: UIScrollView{
override func didMoveToSuperview() {
super.didMoveToSuperview()
self.delegate = self
}
}

class ContentScrollView: UIScrollView{
override func didMoveToSuperview() {
super.didMoveToSuperview()
self.delegate = self
}
}

How to detect when a UIScrollView has finished scrolling In Swift

The delegate method tells you when finished

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
self.stoppedScrolling()
}

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
self.stoppedScrolling()
}
}

func stoppedScrolling() {
println("Scroll finished")
}

How to detect when a UIScrollView has finished scrolling

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self stoppedScrolling];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (!decelerate) {
[self stoppedScrolling];
}
}

- (void)stoppedScrolling {
// ...
}

scrollViewDidEndScrollingAnimation not called

Is this what you need?

Add these funcs to your table view controller...

Edit: forgot to include the scrollViewDidEndScrollingAnimation ...

override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
scrollingFinish()
}

override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
scrollingFinish()
}

override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
scrollingFinish()
}
}

func scrollingFinish() -> Void {
print("Scroll Finished!")
}

How to avoid a double call of scrollViewDidScroll() method while swiping the collectionView?

Add a Bool var to your OnboardingViewController:

var programmedScroll: Bool = false

then, when prev or next button is tapped, instead of:

@IBAction func prevButtonPressed(_ sender: UIButton) {
if currentPage != 0 {
currentPage -= 1
let indexPath = IndexPath(item: currentPage, section: 0)
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
}

do this:

@IBAction func prevButtonPressed(_ sender: UIButton) {
if currentPage != 0 {
currentPage -= 1
let indexPath = IndexPath(item: currentPage, section: 0)
// instead of this
//collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
self.programmedScroll = true
UIView.animate(withDuration: 0.3, animations: {
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
}, completion: { _ in
self.programmedScroll = false
})
}
}

Now your scrollViewDidScroll won't be called during that animation.


Edit

In scrollViewDidScroll implementation:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !programmedScroll {
let visibleRectangle = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRectangle.midX, y: visibleRectangle.midY)
currentPage = collectionView.indexPathForItem(at: visiblePoint)?.row ?? 0
}
}

Edit 2

Using the above approach resulted in a less-than-acceptable scroll effect, because a UICollectionView only renders cells that will be displayed.

When telling the collection view to .scrollToItem with animated: false, the collection view immediately drops the rendering of the cell that will no longer be visible.

So, we'll take the same approach, but find another way to "re-enable" the scrollViewDidScroll code after a Next / Prev button has called .scrollToItem.

In prev/next, let's still set self.programmedScroll = true, but instead of the animation block let's use the built-in animation:

@IBAction func prevButtonPressed(_ sender: UIButton) {
if currentPage != 0 {
currentPage -= 1
let indexPath = IndexPath(item: currentPage, section: 0)
// disable scrollViewDidScroll code execution
self.programmedScroll = true
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
}

@IBAction func nextButtonPressed(_ sender: UIButton) {
if currentPage == slides.count - 1 {
//hide onboarding
} else {
currentPage += 1
let indexPath = IndexPath(item: currentPage, section: 0)
// disable scrollViewDidScroll code execution
self.programmedScroll = true
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
}

then we need to "re-enable" the code to change the page control dot mid-way between cells when dragging, so we'll implement:

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
// re-enable execution of scrollViewDidScroll code
programmedScroll = false
}

That should do it. I updated the repo at: https://github.com/DonMag/TestCollectionViewOnboarding

UIScrollView is not scrolling despite setting delegate

Problem is with these two lines of code

self.scrollView = UIScrollView(frame: CGRect(x: 0, y: displayHeight - displayHeight / 3, width: displayWidth, height: displayHeight))
self.scrollView.contentSize = CGSize(width: displayWidth, height: displayHeight)

Either the scrollView.frame.size should be smaller or the contentSize should be larger. If both are same, the scrollView has no need to scroll.

If only the heights of frame and content size are different, you'll get vertical scroll. if it is the widths, you get horizontal scroll.



Related Topics



Leave a reply



Submit