最近在用UGUI写一个游戏的物品界面,用ScrollView实现物品的浏览。但是遇到一个比较棘手的问题。restrictWithinPanel这个参数虽然可以限制ScrollView中的items,使其最顶端和最低端都不超过scrollView的最顶端和最低端。但当items没有填充满ScrollView的时候,我们需要这些item一直保持在ScrollView的最顶端,也就是无论你怎么拖拽,它都会弹回ScrollView的顶端。
这个可以使用ScrollView的ResetPosition()去实现,实现的过程中配合ScrollView中的onDragFinished时间和onDragStarted事件,在onDragFinished中调用ResetPosition(),可以让items弹回顶端。但是这种弹回几乎是一瞬间发生,弹回速度太快,用户体验太差了。
这里我们用 SpringPanel的Begin方法,可以实现弹回顶端的操作。这里有4个关键
1.ScrollView的onDragFinished事件
2.ScrollView的onDragStarted事件
3. SpringPanel的Begin方法
4.ScrollView的shouldMoveVertically
思路如下,
1.当我们拖拽ScrollView的items时,会触发onDragStarted事件,我们记录下此时的ScrollView本地位置信息startPos(localPosition)
2.当我们释放鼠标或者手指时,会触发onDragFinished事件
3.在onDragFinished事件的注册函数中我们调用SpringPanel的Begin方法,它有三个参数,
static public SpringPanel Begin (GameObject go, Vector3 pos, float strength)
go:你要弹回的gameObject(这里是ScrollView)
pos:你要弹回的位置(我们之前记录的startPos)
strength:弹回力度
4.在我们调用SpringPanel.Begin时,我们要进行判断,判断shouldMoveVertically是true还是false。如果ScrollView被填充满了,返回true,如果没有被填满,返回false。
最后贴一下代码:
private UIScrollView scrollView; private Vector3 startPos = Vector3.zero; private void dragFinished() { if (scrollView != null) { if (!scrollView.shouldMoveVertically) { if (scrollView.dragEffect == UIScrollView.DragEffect.MomentumAndSpring) { // Spring back into place SpringPanel.Begin(scrollView.GetComponent<UIPanel>().gameObject, startPos, 13f).strength = 8f; } } } else { Debug.Log("grid or scroll view is null FUNC:dragFinished POS:PackageTypeClick.cs"); } } private void dragStart() { scrollView = CurrentScrollView.GetComponent<UIScrollView>(); startPos = scrollView.gameObject.transform.localPosition; }