Unity——ScrollView嵌套

解决两层ScrollView嵌套,底层事件无法触发的问题

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

namespace Engine
{
    public class ScrollRectExtend : ScrollRect
    {
        [Range(0,1000)]
        public float stopSlideSpeed = 2.0f; //滑动停止的速度,达到时就执行滑动结束回调

        private ScrollRect parentScrollRect; //父ScrollRect
        private bool isSelf = true;

        private Action stopSlideCallback = null;//停止滑动时的回调
        private bool dragEndFlag = false; //拖拽结束标记



        public void SetParentScrollRect(ScrollRect parentScroll)
        {
            parentScrollRect = parentScroll;
        }


        public void SetStopSlideCallback(Action callback)
        {
            stopSlideCallback = callback;
        }

        public void SetStopSlideSpeed(float speed)
        {
            if (speed < 0.0f)
                speed = 0.0f;

            stopSlideSpeed = speed;
        }
        

        public override void OnBeginDrag(PointerEventData eventData)
        {
            dragEndFlag = false;

            Vector2 touchDeltaPosition;

#if (UNITY_ANDROID || UNITY_IOS)
            touchDeltaPosition = Input.GetTouch(0).deltaPosition;
#else
            float delta_x = Input.GetAxis("Mouse X");
            float delta_y = Input.GetAxis("Mouse Y");
            touchDeltaPosition = new Vector2(delta_x, delta_y);
#endif
            if ((horizontal && vertical) || (parentScrollRect == null))
            {
                isSelf = true;
                base.OnBeginDrag(eventData);
                return;
            }
            if (!horizontal && !vertical)
            {
                isSelf = false;
                parentScrollRect.OnBeginDrag(eventData);
                return;
            }
            if (vertical && !horizontal)
            {
                if (Mathf.Abs(touchDeltaPosition.x) < Mathf.Abs(touchDeltaPosition.y))
                {
                    isSelf = true;
                    base.OnBeginDrag(eventData);
                }
                else
                {
                    isSelf = false;
                    parentScrollRect.OnBeginDrag(eventData);
                }
                return;
            }
            if (!vertical && horizontal)
            {
                if (Mathf.Abs(touchDeltaPosition.x) > Mathf.Abs(touchDeltaPosition.y))
                {
                    isSelf = true;
                    base.OnBeginDrag(eventData);
                }
                else
                {
                    isSelf = false;
                    parentScrollRect.OnBeginDrag(eventData);
                }
                return;
            }
        }
       
        
        public override void OnEndDrag(PointerEventData eventData)
        {
            if (isSelf)
            {
                base.OnEndDrag(eventData);
            }
            else
            {
                parentScrollRect.OnEndDrag(eventData);
            }
            
            dragEndFlag = true;
        }
       

        public override void OnDrag(PointerEventData eventData)
        {
            if (isSelf)
            {
                base.OnDrag(eventData);
            }
            else
            {
                parentScrollRect.OnDrag(eventData);
            }

            dragEndFlag = false;
        }


        private void Update()
        {
            base.LateUpdate();
        }


        protected override void LateUpdate()
        {
            base.LateUpdate();

            bool isStopSlide = CheckIsStopSlide();

            if (isStopSlide && dragEndFlag)
            {
                dragEndFlag = false;

                StopMovement();

                if (stopSlideCallback != null)
                {
                    stopSlideCallback();
                }
            }
        }

        private bool CheckIsStopSlide()
        {
            var diff = 0.0;

            if (horizontal)
            {
                diff = Math.Abs(velocity.x);
            }
            else if (vertical)
            {
                diff = Math.Abs(velocity.y);
            }

            if (diff <= stopSlideSpeed)
                return true;

            return false;
        }
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值