'scrollViewDidScroll' does not catch movement continuously

谁都会走 提交于 2019-12-24 07:34:58

问题


I am writing program to move an UIView named "myView" while scrolling a UITableView, Look at the pic below:

"myView" will change its 'y-coordinate' along with the change of the contentoffset of tableview, the main code I write is:

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 perfectly when I scroll the tableview at a normal speed. However, if I scroll the tableview very fast, 'myview' will stop before reaching the top edge. This is what the log shows:

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 which led to a value jump.

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


回答1:


The likely reason for this occurring is because the touches that are being received by your app are occurring faster than the refresh rate of the screen. Thus certain intermediate scroll points will be missed.

Refresh Rate

iOS devices typically run at 60hz or 60 frames per second. This means that every 1/60s or 0.016666 seconds the screen and digitizer will attempt to refresh the current state of touches.

If your finger moves faster than 0.5 display points in that time period than the next scrollViewDidScroll delegate method will report the newer location and never report the intermediate locations.

Solution

Instead of using the values directly from the delegate method, I would recommend "clamping" the result to your expected range. In this instance it looks like you don't want to receive negative numbers. Meaning if you want the origin y value to be at minimum 0 then you should take the value from the delegate and if it is less than 0 set your View's origin to 0 otherwise use your 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 shouldn't result in jumpy resizing of your view as scrollView should already be reporting this scrollViewDidScroll at near the screen refresh rate.



来源:https://stackoverflow.com/questions/39482753/scrollviewdidscroll-does-not-catch-movement-continuously

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!