Cocos2d x 带有CCControlButton的CCScrollView。如何控制触摸区域?

Cocos2d x 带有CCControlButton的CCScrollView。如何控制触摸区域?,cocos2d-x,ccscrolllayer,Cocos2d X,Ccscrolllayer,我有CCScrollView和带有CCControlButtons的容器,当按钮滚动出可见的CCScrollView区域时,也可以触摸它们。如何控制该区域?我的问题: 有一个包含许多按钮(项目)的滚动视图。上面有两个功能按钮(返回、启动) 当我向下滚动时,项目按钮覆盖在功能按钮上。当我吞下滚动视图上方的所有触摸时,我将丢失功能按钮。所以我必须找到另一个解决办法 当我开始拖动滚动视图时,一个项目按钮被按下。当我结束时,将执行按钮操作。这很烦人 但解决办法是有的。我已经创建了新的CCControlB

我有CCScrollView和带有CCControlButtons的容器,当按钮滚动出可见的CCScrollView区域时,也可以触摸它们。如何控制该区域?

我的问题: 有一个包含许多按钮(项目)的滚动视图。上面有两个功能按钮(返回、启动)

  • 当我向下滚动时,项目按钮覆盖在功能按钮上。当我吞下滚动视图上方的所有触摸时,我将丢失功能按钮。所以我必须找到另一个解决办法

  • 当我开始拖动滚动视图时,一个项目按钮被按下。当我结束时,将执行按钮操作。这很烦人

  • 但解决办法是有的。我已经创建了新的CCControlButton。它检查是否在scrollview外单击或拖动。该按钮用于“项目”按钮

    bool ControlButtonForScrolling::checkIfTouchIsInsideScrollView(CCTouch *pTouch)
    {
        CCPoint touchLocation = pTouch->getLocation(); // Get the touch position
        touchLocation = _scrollView->getParent()->convertToNodeSpace(touchLocation);
        CCRect bBox=_scrollView->boundingBox();
        bool result = bBox.containsPoint(touchLocation);
        return result;
    }
    
    bool ControlButtonForScrolling::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
    {
        bool isInside = this->checkIfTouchIsInsideScrollView(pTouch);
        if (isInside) {
            return CCControlButton::ccTouchBegan(pTouch, pEvent);
        }
        else
        {
            return false;
        }
    }
    
    void ControlButtonForScrolling::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
    {
        CCControlButton::ccTouchMoved(pTouch, pEvent);
        _scrollWasDragged = true; // information about dragging is stored to prevent sending action
    }
    
    void ControlButtonForScrolling::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
    {
        // this method is a copy of CCControlButton::ccTouchEnded except lines with _scrollWasDragged
        m_eState = CCControlStateNormal;
        m_isPushed = false;
        setHighlighted(false);
    
        if (!_scrollWasDragged)
        {
            if (isTouchInside(pTouch))
            {
                sendActionsForControlEvents(CCControlEventTouchUpInside);
            }
            else
            {
                sendActionsForControlEvents(CCControlEventTouchUpOutside);
            }
        }
        _scrollWasDragged = false;
    }
    
    我的问题: 有一个包含许多按钮(项目)的滚动视图。上面有两个功能按钮(返回、启动)

  • 当我向下滚动时,项目按钮覆盖在功能按钮上。当我吞下滚动视图上方的所有触摸时,我将丢失功能按钮。所以我必须找到另一个解决办法

  • 当我开始拖动滚动视图时,一个项目按钮被按下。当我结束时,将执行按钮操作。这很烦人

  • 但解决办法是有的。我已经创建了新的CCControlButton。它检查是否在scrollview外单击或拖动。该按钮用于“项目”按钮

    bool ControlButtonForScrolling::checkIfTouchIsInsideScrollView(CCTouch *pTouch)
    {
        CCPoint touchLocation = pTouch->getLocation(); // Get the touch position
        touchLocation = _scrollView->getParent()->convertToNodeSpace(touchLocation);
        CCRect bBox=_scrollView->boundingBox();
        bool result = bBox.containsPoint(touchLocation);
        return result;
    }
    
    bool ControlButtonForScrolling::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
    {
        bool isInside = this->checkIfTouchIsInsideScrollView(pTouch);
        if (isInside) {
            return CCControlButton::ccTouchBegan(pTouch, pEvent);
        }
        else
        {
            return false;
        }
    }
    
    void ControlButtonForScrolling::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
    {
        CCControlButton::ccTouchMoved(pTouch, pEvent);
        _scrollWasDragged = true; // information about dragging is stored to prevent sending action
    }
    
    void ControlButtonForScrolling::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
    {
        // this method is a copy of CCControlButton::ccTouchEnded except lines with _scrollWasDragged
        m_eState = CCControlStateNormal;
        m_isPushed = false;
        setHighlighted(false);
    
        if (!_scrollWasDragged)
        {
            if (isTouchInside(pTouch))
            {
                sendActionsForControlEvents(CCControlEventTouchUpInside);
            }
            else
            {
                sendActionsForControlEvents(CCControlEventTouchUpOutside);
            }
        }
        _scrollWasDragged = false;
    }
    

    受Tomasz答案的启发,我创建了一个替代解决方案,也继承了
    CCControlButton

    bool ScrollableButton::isTouchInside(CCTouch *touch) {
      return !dragging && CCControlButton::isTouchInside(touch);
    }
    
    bool ScrollableButton::ccTouchBegan(CCTouch *touch, CCEvent *event) {
      dragging = false;
      return CCControlButton::ccTouchBegan(touch, event);
    }
    
    void ScrollableButton::ccTouchMoved(CCTouch *touch, CCEvent *event) {
      if (!dragging && ccpDistance(touch->getLocation(), touch->getStartLocation()) > 25) {
        dragging = true;
      }
      CCControlButton::ccTouchMoved(touch, event);
    }
    
    void ScrollableButton::ccTouchEnded(CCTouch *touch, CCEvent *event) {
      CCControlButton::ccTouchEnded(touch, event);
      dragging = false;
    }
    
    void ScrollableButton::ccTouchCancelled(CCTouch *touch, CCEvent *event) {
      CCControlButton::ccTouchCancelled(touch, event);
      dragging = false;
    }
    
    秘密酱汁是对
    istouchind
    函数的覆盖,该函数将返回
    false
    ,即使触摸在内部,但已被移动。这样,当您开始滚动时,按钮也将释放其“缩放”状态


    它还增加了一个小的公差系数,所以如果触摸只移动了一点点,它仍然被认为是“点击”。在上面的示例中,该系数硬编码为25。

    受Tomasz答案的启发,我创建了一个替代解决方案,也继承了
    CCControlButton

    bool ScrollableButton::isTouchInside(CCTouch *touch) {
      return !dragging && CCControlButton::isTouchInside(touch);
    }
    
    bool ScrollableButton::ccTouchBegan(CCTouch *touch, CCEvent *event) {
      dragging = false;
      return CCControlButton::ccTouchBegan(touch, event);
    }
    
    void ScrollableButton::ccTouchMoved(CCTouch *touch, CCEvent *event) {
      if (!dragging && ccpDistance(touch->getLocation(), touch->getStartLocation()) > 25) {
        dragging = true;
      }
      CCControlButton::ccTouchMoved(touch, event);
    }
    
    void ScrollableButton::ccTouchEnded(CCTouch *touch, CCEvent *event) {
      CCControlButton::ccTouchEnded(touch, event);
      dragging = false;
    }
    
    void ScrollableButton::ccTouchCancelled(CCTouch *touch, CCEvent *event) {
      CCControlButton::ccTouchCancelled(touch, event);
      dragging = false;
    }
    
    秘密酱汁是对
    istouchind
    函数的覆盖,该函数将返回
    false
    ,即使触摸在内部,但已被移动。这样,当您开始滚动时,按钮也将释放其“缩放”状态


    它还增加了一个小的公差系数,所以如果触摸只移动了一点点,它仍然被认为是“点击”。在上面的示例中,该系数硬编码为25。

    CCScrollView有许多类似的问题。甚至scrollview也不能平滑滚动。有相同的问题,并在本机表视图中创建视图:(CCScrollView有许多类似的问题。即使scrollview也无法顺利滚动。有相同的问题,并在本机表视图中创建视图:(