[Unity 사례] 중첩된 슬라이딩 목록

구현 내용:

Unity의 중첩된 슬라이딩 목록인 외부 슬라이딩 뷰(외부 스크롤 뷰)는 여러 내부 슬라이딩 뷰(내부 스크롤 뷰)를 포함합니다. 외부 슬라이딩 뷰는 수직 또는 수평 슬라이딩을 담당하고 내부 슬라이딩 뷰는 기본 슬라이딩 뷰를 담당합니다. 외부 슬라이딩 수직 또는 수평으로 스와이프하여 사용자가 외부 목록을 한 방향으로, 내부 목록을 다른 방향으로 슬라이드하여 복잡한 데이터 표시 및 상호 작용을 달성할 수 있습니다.

주요 아이디어:

이벤트 투명 전송을 사용하여 슬라이드 시작 시 사용자의 현재 슬라이딩 방향을 감지합니다. 현재 목록의 슬라이딩 방향이 수직인데 사용자가 수평 명령을 입력하는 경우(예: ExecuteEvents.Excute 메소드를 사용하여 이벤트를 투명하게 전달함) 상위 슬라이딩 목록에 대한 핵심 코드는 다음과 같습니다.

// 根据位置的变化确定拖拽方向
dragDirection = Mathf.Abs(eventData.delta.x) > Mathf.Abs(eventData.delta.y)
  ? Direction.Horizontal
  : Direction.Vertical;

// 如果存在父级且拖拽方向与当前方向不同
if (parent != null && curDirection != dragDirection)
{
  // 在父级上执行开始拖拽事件
  ExecuteEvents.Execute(parent.gameObject, eventData, ExecuteEvents.beginDragHandler);
  return;
}
전체 코드는 다음과 같습니다.
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ScrollViewEX : ScrollRect
{
    // 枚举表示滚动方向
    private enum Direction
    {
        Horizontal,
        Vertical,
    }

    // 当前 ScrollViewEX 的滚动方向
    private Direction curDirection;

    // 拖拽期间的滚动方向
    private Direction dragDirection;

    // 对父级 ScrollViewEX 的引用(如果有的话)
    private ScrollViewEX parent;
    
    protected override void Awake()
    {
        base.Awake();

        // 如果未分配父级,请在父级层次结构中查找它
        if (parent == null)
        {
            parent = transform.parent.GetComponentInParent<ScrollViewEX>();
        }

        // 根据 'horizontal' 属性确定并设置当前滚动方向
        curDirection = horizontal ? Direction.Horizontal : Direction.Vertical;
    }

    // 开始拖拽时调用
    public override void OnBeginDrag(PointerEventData eventData)
    {
        // 根据位置的变化确定拖拽方向
        dragDirection = Mathf.Abs(eventData.delta.x) > Mathf.Abs(eventData.delta.y)
            ? Direction.Horizontal
            : Direction.Vertical;

        // 如果存在父级且拖拽方向与当前方向不同
        if (parent != null && curDirection != dragDirection)
        {
            // 在父级上执行开始拖拽事件
            ExecuteEvents.Execute(parent.gameObject, eventData, ExecuteEvents.beginDragHandler);
            return;
        }

        // 如果条件不符合,则继续基本的 OnBeginDrag
        base.OnBeginDrag(eventData);
    }

    // 拖拽期间调用
    public override void OnDrag(PointerEventData eventData)
    {
        // 如果存在父级且拖拽方向与当前方向不同
        if (parent != null && curDirection != dragDirection)
        {
            // 在父级上执行拖拽事件
            ExecuteEvents.Execute(parent.gameObject, eventData, ExecuteEvents.dragHandler);
            return;
        }

        // 如果条件不符合,则继续基本的 OnDrag
        base.OnDrag(eventData);
    }

    // 拖拽结束时调用
    public override void OnEndDrag(PointerEventData eventData)
    {
        // 如果存在父级且拖拽方向与当前方向不同
        if (parent != null && curDirection != dragDirection)
        {
            // 在父级上执行结束拖拽事件
            ExecuteEvents.Execute(parent.gameObject, eventData, ExecuteEvents.endDragHandler);
            return;
        }

        // 如果条件不符合,则继续基本的 OnEndDrag
        base.OnEndDrag(eventData);
    }

    // 用户滚动时调用
    public override void OnScroll(PointerEventData data)
    {
        // 如果存在父级且拖拽方向与当前方向不同
        if (parent != null && curDirection != dragDirection)
        {
            // 在父级上执行滚动事件
            ExecuteEvents.Execute(parent.gameObject, data, ExecuteEvents.scrollHandler);
            return;
        }

        // 如果条件不符合,则继续基本的 OnScroll
        base.OnScroll(data);
    }
}

추천

출처blog.csdn.net/lel18570471704/article/details/130883015