11

I'm implementing UIScrollViewDelegate and doing a lot of stuff with it. However, I just found an annoying issue.

I expect scrollViewDidEndDecelerating: to be called always after scrollViewWillBeginDecelerating:. However, if I simply touch my ScrollView (actually I'm touching a button inside the scrollView), scrollViewDidEndDecelerating: gets called and scrollViewWillBeginDecelerating: was not called.

So how can I avoid scrollViewDidEndDecelerating: being called when I simply press a button inside my UIScrollView?

Thank you!

LocoMike
  • 5,626
  • 5
  • 30
  • 43

2 Answers2

1

I had the same problem I fixed it by making a variable that hold the current page num and compare it with the local current page variable if they r equal then don't proceed.

var currentPage : CGFloat = 0.0
var oldPage : CGFloat = 0.0

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView){
    // Test the offset and calculate the current page after scrolling ends

    let pageWidth:CGFloat = scrollView.frame.width
    let currentPage:CGFloat = floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1
    // Change the indicator
    print("that's the self.currentPage \(self.currentPage) and that's the current : \(currentPage)")

    guard  self.currentPage != currentPage else { return }
    oldPage = self.currentPage
    self.currentPage = currentPage;

    print("that's the old \(oldPage) and that's the current : \(currentPage)")

       //Do something
}
killvak
  • 96
  • 8
1

Create a member BOOL called buttonPressed or similar and initialise this to false in your init: method.

Set the BOOL to true whenever your button/s are hit, and then perform the following check:

-(void)scrollViewDidEndDecelerating: (UIScrollView*)scrollView
{
    if (!buttonPressed)
    {
        // resume normal processing
    }
    else
    {
        // you will need to decide on the best place to reset this variable.
        buttonPressed = NO;
    }
}
Luke
  • 11,426
  • 43
  • 60
  • 69
  • Hey, yes, that is one possible answer. However, what I really want is that method not being called, specially when **scrollViewWillBeginDecelerating:** was not called. FFor this kind of hack, I guess it could be more useful to perform button action with a slight delay, so that the touches will be finished. Also I can not know for sure that it was my button the one that triggered that method call, so I could never be sure if I'm resetting that var in the correct place... :( – LocoMike Dec 01 '11 at 10:52
  • It sounded like you wanted a hack answer, but ok. I'd have another look at the descriptions of the delegate methods in the class reference, setup all the methods you've listed in your question and understand how/why/when they're all being called. Also, if you set tags to your buttons and implement a -(void)buttonPressed: (id)sender method, you can react to a unique button press more efficiently. – Luke Dec 01 '11 at 11:10
  • 2
    The button was how I found the problem. But the problem itself is that *scrollViewDidEndDecelerating:** is being called when just touching a button inside the scrollview. There is no deceleration, there is not willBeginDragging: ... Thanks anyway for your effort. It maybe that that method is being called every time you simply tap the scrollView, even if you tapped an innerview that will take the touch (like a UIButton) – LocoMike Dec 01 '11 at 14:23