这里我主要分析一下UIScrollView滑动的实现。
首先来看下UIScrolView里的void Press(bool pressed)函数;
if (pressed)
{
// Remove all momentum on press
//按下时移除所有动力;
mMomentum = Vector3.zero;
mScroll = 0f;
// Disable the spring movement
//隐藏弹簧运动;
DisableSpring();
// Remember the hit position
//记录触碰的点;
mLastPos = UICamera.lastWorldPosition;
// Create the plane to drag along
mPlane = new Plane(mTrans.rotation * Vector3.back, mLastPos);
// Ensure that we're working with whole numbers, keeping everything pixel-perfect
Vector2 co = mPanel.clipOffset;
co.x = Mathf.Round(co.x);
co.y = Mathf.Round(co.y);
mPanel.clipOffset = co;
Vector3 v = mTrans.localPosition;
v.x = Mathf.Round(v.x);
v.y = Mathf.Round(v.y);
mTrans.localPosition = v;
}
以上是Press函数中的部分代码,它主要做把滑动后缓冲的动力归零、关闭滑动后的缓冲运动(本文所谓的滑动后是指手指离开屏幕)、记录按下点的世界坐标、创建一个平面;其实就是为滑动做准备;
好了,再来看看public void Drag ()函数:
<span style="white-space:pre"> </span>Ray ray = smoothDragStart ?
UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos - mDragStartOffset) :
UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos);
float dist = 0f;
if (mPlane.Raycast(ray, out dist))
{
Vector3 currentPos = ray.GetPoint(dist);
Vector3 offset = currentPos - mLastPos;
mLastPos = currentPos;
if (offset.x != 0f || offset.y != 0f || offset.z != 0f)
{
offset = mTrans.InverseTransformDirection(offset);
if (movement == Movement.Horizontal)
{
offset.y = 0f;
offset.z = 0f;
}
else if (movement == Movement.Vertical)
{
offset.x = 0f;
offset.z = 0f;
}
else if (movement == Movement.Unrestricted)
{
offset.z = 0f;
}
else
{
offset.Scale((Vector3)customMovement);
}
offset = mTrans.TransformDirection(offset);
}
// Adjust the momentum
if (dragEffect == DragEffect.None) mMomentum = Vector3.zero;
else mMomentum = Vector3.Lerp(mMomentum, mMomentum + offset * (0.01f * momentumAmount), 0.67f);
// Move the scroll view
if (!iOSDragEmulation || dragEffect != DragEffect.MomentumAndSpring)
{
MoveAbsolute(offset);
}
else
{
Vector3 constraint = mPanel.CalculateConstrainOffset(bounds.min, bounds.max);
if (constraint.magnitude > 1f)
{
MoveAbsolute(offset * 0.5f);
mMomentum *= 0.5f;
}
else
{
MoveAbsolute(offset);
}
}
这是该函数的主要部分了其实它主要做了三件事:1、计算滑动偏移;2、计算缓冲动力;3、移动;
滑动偏移没什么好说的,就是这一帧和上一帧比较手指移动的距离;重点来看看下面一段代码
mMomentum = Vector3.Lerp(mMomentum, mMomentum + offset * (0.01f * momentumAmount), 0.67f);
这段代码就是记录缓冲动力的,可以看到这个值一直是在叠加的,从press()函数可以知道只有按下时这mMomentum才会归零,那么如果我手指按下慢慢的滑mMomentum的值会很大,当我放手时ScrollView将会继续滑动很大的距离,然而实际上是不会的,这是为什么呢?原因就在LataUpdate()函数里;
<pre name="code" class="csharp">NGUIMath.SpringDampen(ref mMomentum, 9f, delta);
对,没错就是这个家伙;这个函数是用来抑制缓冲动力的,它在手指按下的时候运行,手指按下的时间越长mMomentum值就会越小;这样就算滑再慢mMomentum值叠加的再大,这段代码都会让它越来越小;这样就实现了快速滑动后会有一段缓冲距离,而慢滑的缓冲小或是没有;
</pre><pre name="code" class="csharp"><span style="white-space:pre"> </span>好了就写这么多,第一次写博客,写的不好请见谅,有哪说的不对的请大神指教。