CCScrollView с помощью CCControlButton. Как управлять сенсорной областью?

У меня есть CCScrollView с контейнером с CCControlButtons, когда кнопки прокручиваются из видимой области CCScrollView, к ним также можно прикоснуться. Как я могу контролировать область?

2 ответа

Решение

Мои проблемы: есть scrollView со многими кнопками (элементами). Над ним расположены 2 функциональные кнопки (возврат, запуск).

  1. Когда я прокручиваю вниз кнопки элемента, они перекрывают функциональные кнопки. Когда я глотаю все прикосновения над моим прокруткой, я теряю свои функциональные кнопки. Поэтому я должен найти другое решение.

  2. Когда я начинаю перетаскивать вид прокрутки, нажимается кнопка элемента. Когда я закончу, действие кнопки будет выполнено. Это очень раздражает.

Но есть решение. Я создал новый CCControlButton. Он проверяет, был ли нажат за пределами прокрутки просмотра или был перетащен. Кнопка используется для пунктов кнопок.

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:

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;
}

Секретный соус - это переопределение isTouchInside функция, которая будет возвращать false даже если касание внутри, но был перемещен. Таким образом, кнопка также освободит свое "увеличенное" состояние, как только вы начнете прокручивать.

Он также добавляет небольшой допуск, поэтому, если касание немного перемещается, оно все равно считается "щелчком". Этот фактор жестко закодирован на 25 в примере выше.

Другие вопросы по тегам