'scrollViewDidScroll' 不会连续捕捉移动 [英] 'scrollViewDidScroll' does not catch movement continuously

查看:31
本文介绍了'scrollViewDidScroll' 不会连续捕捉移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写程序以在滚动 UITableView 时移动名为myView"的 UIView,请看下图:

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

"myView"会随着tableview的contentoffset的改变而改变它的'y坐标',我写的主要代码是:

"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                                    
}

当我以正常速度滚动 tableview 时,这非常有效.但是,如果我非常快速地滚动 tableview,'myview' 将在到达顶部边缘之前停止.这是日志显示的内容:

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

似乎委托方法 scrollViewDidScroll 没有捕获导致值跳转的每个滚动移动.

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!

推荐答案

发生这种情况的可能原因是您的应用程序接收到的触摸发生得比屏幕的刷新率快.因此某些中间滚动点将被遗漏.

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.

iOS 设备通常以 60hz 或每秒 60 帧的速度运行.这意味着每 1/60 秒或 0.016666 秒,屏幕和数字化仪将尝试刷新当前触摸状态.

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.

如果您的手指在该时间段内移动速度超过 0.5 个显示点,则下一个 scrollViewDidScroll 委托方法将报告较新的位置,而从不报告中间位置.

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.

我建议不要直接使用委托方法中的值,而是建议将结果限制"到您的预期范围内.在这种情况下,您似乎不想收到负数.这意味着如果您希望原点 y 值至少为 0,那么您应该从委托中获取该值,如果它小于 0,请将您的视图的原点设置为 0,否则使用您的计算结果.

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.

示例:

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                                    
}

注意:这不应导致您的视图突然调整大小,因为 scrollView 应该已经在接近屏幕刷新率的情况下报告此 scrollViewDidScroll.

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.

这篇关于'scrollViewDidScroll' 不会连续捕捉移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆