0

I'm using a timer and print the contentOffset.y of a UIScrollView to track it all the time.

But the problems is UIScrollView updates its contentOffset value only after it is decelerated.

I want to know the contentOffset.y value in every millisecond of timer and how can I do that? If I cannot use contentOffset of the UIScrollView at all, is there any other way to track similar value to contentOffset.y of a scrollView?

I'm using swift. Thank you.

thura oo
  • 493
  • 1
  • 6
  • 18
  • Could you post the code of whatever you have tried until now? – Pooja Srivastava Sep 29 '16 at 10:41
  • `let timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.timTick), userInfo: nil, repeats: true) //declare the time func timTick() { let scrOffset = scrollView.contentOffset.y print(scrOffset) } //print every 0.01 second` @PoojaSrivastava – thura oo Sep 29 '16 at 10:47

1 Answers1

3

Instead of tracking the changes by polling with a timer, you can observe any changes to the value. UIScrollView has a delegate property that gets called for scroll events (see UIScrollViewDelegate), and contentOffset is KVO compliant.

Or you could subclass UIScrollView and try overriding the setters (either for contentOffset or bounds where origin is the the offset, I'm not sure which one, if either, the class calls internally - using the delegate is the preferred solution).

Arkku
  • 41,011
  • 10
  • 62
  • 84
  • Thank you for your answer. But UIScrollView delegate methods are only `WillBegin..` and `DidEnd...` methods which call only when I **finish or begin** dragging, scrolling or the scrollView itself **finish or begin** decelerating. I need to know the value **every time** whether my finger is touching the phone or not (or) the scroll View finished decelerating or not. I don't have any idea how to override the setters that you mentioned. @Arkku – thura oo Sep 29 '16 at 11:04
  • @thuraoo The `scrollViewDidScroll:` is being called during scroll whenever the offset changes, not only begin/end. (Just try it.) Inside that method you can check `isDragging`, `isTracking` and/or `isDecelerating` properties of the scroll view. You can also override the `willBegin` and `didEnd` for dragging and/or decelerating if you need some special handling at those events. – Arkku Sep 29 '16 at 11:14
  • @thuraoo As for how to override the setters, as you would override any method (remember to call the `super` implementation). But it is highly unlikely to be necessary, I have done a lot of stuff that requires accurately tracking the scroll view's movements and `scrollViewDidScroll:` of the delegate is almost always sufficient. – Arkku Sep 29 '16 at 11:15
  • @thuraoo In any case, a timer is a _horrible_ solution to the problem. You will be calling it unnecessarily most of the time, your app will wake up for the pointless timer 100 times a second, and in the end the responsiveness will still be worse than tracking the actual changes. – Arkku Sep 29 '16 at 11:18
  • Now my problem is solved. As the method says `scrollViewDidScroll` I thought that it will call only after decelerating. Now I tried it and it works. **Thank you very much** for you answers and comments. – thura oo Sep 29 '16 at 11:37