CCScrollView not bouncing off the bottom

Hi!

Im using cocos2dx 2.2.4 and i have an issue with CCScrollView
The thing is: when i swipe it from bottom to top - it perfectly bounces off the top.
But then i swipe it from top to bottom - it does not, the content of scroll view just goes downwards as long as i swipe it and in the end disappears from the visible area of scrollview.

What to do??

Here is how i initialize scrollview:

CCScrollView* scrollView = CCScrollView::create( background->getContentSize() );
scrollView->setTouchPriority( kCCMenuHandlerPriority );
scrollView->setDirection( kCCScrollViewDirectionVertical );
background->addChild( scrollView );
    
CCScale9Sprite* testPlaceholder = CCScale9Sprite::create( "whitepixel.png", CCRect( 0, 0, scrollView->getViewSize().width, scrollView->getViewSize().height ) );
testPlaceholder->setColor( ccBLUE );
scrollView->addChild( testPlaceholder );

background is just a CCScale9Sprite, with size 500x500

In the mean time CCTableView which use CCScrollView works just as i need it: it bounces off both top and bottom edges, but i can’t find whats the difference between my using CCScrollView and CCTableView’s one.

You might need to give ui::ScrollView a try. It supports bouncing well.

Currently the implementation of CCScrollView is not very good.

Hi @owen

i am also having some questions for you about ScrollView

this is my code…

`#include "ChallengeScene.h"
#include "GameLoadScene.h"
#include "Challenge1.h"

#include "extensions/cocos-ext.h"

USING_NS_CC;
USING_NS_CC_EXT;

class ScrollViewWithTouchableItems: public ScrollView
{
public :
    static ScrollViewWithTouchableItems* create(Size size, Node* container)
    {
        ScrollViewWithTouchableItems* pRet = new ScrollViewWithTouchableItems();
        if (pRet && pRet->initWithViewSize(size, container))
        {
            pRet->_touchListener->setSwallowTouches(false);
            pRet->autorelease();
        }
        else
        {
            CC_SAFE_DELETE(pRet);
        }
        return pRet;
    }
};

class ControlButtonUsable: public ControlButton
{
public :
    static ControlButtonUsable* create(Scale9Sprite* sprite)
    {
        ControlButtonUsable *pRet = new ControlButtonUsable();
        pRet->initWithBackgroundSprite(sprite);
        pRet->autorelease();
        return pRet;
    }

    void setTouchDownHandler(Ref* target, Handler action)
    {
        addTargetWithActionForControlEvent(target, action, Control::EventType::TOUCH_DOWN);
    }
};

Scene* Challenge::createScene(bool wasPushed)
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();

    // 'layer' is an autorelease object
    auto layer = Challenge::create();

    // some funny comment about humpty-dumpty goes here
    layer->_wasPushed = wasPushed;

    // add layer as a child to scene
    // attaches all the children to the existing physics world as well
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool Challenge::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }

    _wasPushed = false;
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Point origin = Director::getInstance()->getVisibleOrigin();

    // scroll container
    auto scrollContainer = Layer::create();
    scrollContainer->setAnchorPoint(Vec2::ZERO);
    scrollContainer->setPosition(Vec2::ZERO);
    scrollContainer->setContentSize(Size(visibleSize.width , 2*visibleSize.height));
    this->addChild(scrollContainer);


    auto wd = scrollContainer->getContentSize().width;
    auto ht = scrollContainer->getContentSize().height;

    // container item icons
    auto addChallenge =
    [&](std::string fileName, int id) -> void
    {
        auto chal_sprite = Scale9Sprite::create(fileName);
        auto chal = ControlButtonUsable::create(chal_sprite);
        chal->setTag(id);
        chal->setTouchDownHandler(this, cccontrol_selector(Challenge::touchDownAction));
        chal->setPosition(wd/5, (5 - id) * ht/5);
        scrollContainer->addChild(chal);

        std::stringstream sstr;
        sstr << "challenge " << id;
        auto label = LabelTTF::create(sstr.str(), "fonts/Marker Felt.ttf" , 20);
        label->setPosition(3*wd/5, (5 - id) * ht/5);
        scrollContainer->addChild(label);
    };

    // TODO: need to create a proper scale9 png for this
    addChallenge("chalbox.png", 1);
    addChallenge("chalbox.png", 2);
    addChallenge("chalbox.png", 3);
    addChallenge("chalbox.png", 4);

    // scroll view
    auto scrollview = ScrollViewWithTouchableItems::create(visibleSize, scrollContainer);
    scrollview->setDirection(ScrollView::Direction::VERTICAL);
    scrollview->setPosition(Vec2::ZERO);

    this->addChild(scrollview);

    this->setKeypadEnabled(true);

    return true;
}

void Challenge::onKeyReleased(cocos2d::EventKeyboard::KeyCode keycode , cocos2d::Event *event)
{
    if (_wasPushed)
        Director::getInstance()->end();
    else
        Director::getInstance()->popScene();
}

void Challenge::touchDownAction(Ref *sender, Control::EventType controlEvent)
{
    int sceneId = dynamic_cast<Node *>(sender)->getTag();
    auto scene = Challenge1::createScene();
    Director::getInstance()->replaceScene(scene);
}

The problem is it starts from bottom of the layer, but i want it to start from the top…
so i get to see challenge 3 and challenge 4, but it should start from challenge 1…
i am sure… you can help… :smile:

you may add
scrollView->setContentSize( background->getContentSize() );
in 2.1.3 it works,i don’t know if there is change in CCScrollView from 2.1.3 to 2.2.4

thanks! setting content size helped.

I’m sorry for the late reply.

You could call setContentOffset function to move the CCScrollView start from the top rather that the bottom.

yup… thanks for replying @owen

i’ve already figured out. :smile: