最近在用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; }