"scrollViewDidScroll" does not commit motion continuously

I am writing a program to move a UIView with the name "myView" while scrolling through a UITableView. Look at the pic below:

enter image description here enter image description here

"myView" will change its "y coordinate" along with changing the contentoffset tableview, the main code that I write:

func scrollViewDidScroll(scrollView: UIScrollView) { let off_y = scrollView.contentOffset.y let new_y = originalMyViewY - off_y if new_y <= 0 { print("bad new_y : \(new_y)") return } else { print("right new_y: \(new_y)") } var frame = self.myView.frame frame.origin.y = new_y self.myView.frame = frame } 

This works great when I look at a table at normal speed. However, if I scroll through the table view very quickly, "myview" will stop until it reaches the top edge. This shows the log:

 right new_y: 56.0 bad new_y : -92.5 bad new_y : -153.5 bad new_y : -206.0 

It seems that the delegate method scrollViewDidScroll did not catch every scroll movement that led to a jump in the value.

I want to know the reason and how to fix it, thanks!

+1
ios uitableview uiscrollview
source share
1 answer

The likely reason for this is that the touch that your application receives is faster than the refresh rate of the screen. Thus, some intermediate scroll points will be skipped.

Update frequency

iOS devices typically run at 60 Hz or 60 frames per second. This means that every 1/60 seconds or 0.016666 seconds, the screen and digitizer will try to update the current state of touches.

If your finger moves faster than the 0.5 points displayed during this time period than the next delegate method scrollViewDidScroll will report a new location and never report intermediate locations.

Decision

Instead of using the values ​​directly from the delegate method, I would recommend clamping the result to your expected range. In this case, it looks like you don't want to get negative numbers. If you want the value of the beginning y to be at least 0, you must take the value from the delegate, and if it is less than 0, set the "Start of presentation" parameter to "0", otherwise use the calculated result.

Example:

 func scrollViewDidScroll(scrollView: UIScrollView) { let off_y = scrollView.contentOffset.y var new_y = originalMyViewY - off_y // make this mutable so we can change it in the <= 0 block if new_y <= 0 { print("y is less than 0, clamp y origin to 0") new_y = 0 } else { print("right new_y: \(new_y)") } var frame = self.myView.frame frame.origin.y = new_y self.myView.frame = frame } 

Note. . This should not cause a drastic change in the size of your view, since scrollView should already be reporting this scrollViewDidScroll at a refresh rate of the screen.

+2
source share

All Articles