ScrollView的OnValueChanged

关于限制scrollView滚动

  • 这个限制滚动的需求,其实只能放置在LateUpdate函数里面进行操作
  • ScrollView在update里面进行了移动,在lateupdate里面判断位置是否超过限制,并进行卡死
  • 但是我为了图方便,在别人写好的接口里面进行开发,结果只要滑动速度过快,就会无法卡住。
计算某个具体元素的位置
  • 因为这涉及到计算在ScrollView中某个元素在列表中的位置。
  • 其实还是蛮难计算的。
  • 这里以垂直滚动为例子。
  • 首先我们要算出滚动的距离
滚动的距离 = content的高度-视口的高度
  • value = 计算第i个元素的高度/滚动距离

  • 再把scrollRect的VerticalNormalization设置为这个值

  • 一个坑

using UnityEngine;
using UnityEngine.UI;

public class ScrollDistanceCalculator : MonoBehaviour
{
    public ScrollRect scrollRect;

    void Update()
    {
        // 获取视口的大小
        Vector2 viewportSize = new Vector2(scrollRect.viewport.rect.width, scrollRect.viewport.rect.height);

        // 获取内容的大小
        Vector2 contentSize = new Vector2(scrollRect.content.rect.width, scrollRect.content.rect.height);

        // 获取当前的归一化位置
        Vector2 normalizedPosition = scrollRect.normalizedPosition;

        // 计算像素距离
        float horizontalDistance = (contentSize.x - viewportSize.x) * normalizedPosition.x;
        float verticalDistance = (contentSize.y - viewportSize.y) * normalizedPosition.y;

        // 打印像素距离
        Debug.Log("Horizontal Distance: " + horizontalDistance);
        Debug.Log("Vertical Distance: " + verticalDistance);
    }
}

  • 我在设置的时候使用的是
 Debug.Log($"ViewPort height_{GetComponent<ScrollRect>().viewport.rect.height}");
Debug.Log($"ViewPort height_{GetComponent<ScrollRect>().viewport.sizeDelta.y}");
  • ViewPort的SizeDelta和Rect的height是不一样的。这就涉及到另一个知识点。SizeDelta是什么,Rect又是什么

  • 滚动到第i个元素的实现

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

    }

    public enum Align
    {
        Top,
        Middle,
        Bottom,
    }
    public Align align;

    public int ItemIndex;
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.K))
        {
            Debug.Log($"content height_{GetComponent<ScrollRect>().content.rect.height}");
            Debug.Log($"content size_Y{GetComponent<ScrollRect>().content.sizeDelta.y}");

            Debug.Log($"content height_{GetComponent<ScrollRect>().viewport.rect.height}");
            Debug.Log($"content height_{GetComponent<ScrollRect>().viewport.sizeDelta.y}");


        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            var btns = GetComponent<ScrollRect>().content.GetComponentsInChildren<UnityEngine.UI.Button>();
            int index = 0;
            foreach (var item in btns)
            {
                item.transform.Find("Text").GetComponent<TextMeshProUGUI>().text = $"{index++}";
            }
            var sumHeight = GetComponent<ScrollRect>().content.rect.height - GetComponent<ScrollRect>().viewport.rect.height;
            float value = 0;
            for (int i = 0; i < ItemIndex; i++)
            {
                value += btns[i].GetComponent<RectTransform>().rect.height;
            }

            switch (align)
            {
                case Align.Top:
                    value = value;
                    break;
                case Align.Middle:
                    value = value + btns[ItemIndex].GetComponent<RectTransform>().rect.height / 2;
                    break;
                case Align.Bottom:
                    value = value + btns[ItemIndex].GetComponent<RectTransform>().rect.height;

                    break;
                default:
                    break;
            }
            GetComponent<ScrollRect>().verticalNormalizedPosition = 1 - value / sumHeight;
        }


    }
}

你可能感兴趣的:(unity)