UIScrollView源码分析(一)

这里我主要分析一下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>好了就写这么多,第一次写博客,写的不好请见谅,有哪说的不对的请大神指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值