CCScrollview is scrolling upside down

Hey, i’m using CCScrollView to show a list of nodes. Here is the initialization:
@ ListLayer* list = ListLayer::create();
list~~>setPosition;
list~~>setContentSize(CCSizeMake(250, 900));@

@ CCScrollView* scrollView = CCScrollView::create(CCSizeMake(250, 656), NULL);
scrollView~~>setPosition;
scrollView~~>setContainer(list);
scrollView~~>setDirection;
list~~>setParentScrollView(scrollView);
scrollView->updateInset();
addChild(scrollView);@

The scrolling works, but the thing is that when i scroll upwards (going down in the list) the list bounces back to the original position. If i scroll downwards it does not bounce back and it leaves a blank space at the top. The behavior is exactly the opposite than the one i want. How can i fix this?
BTW; i’m using the last version of CCScrollView (https://github.com/cocos2d/cocos2d-x/blob/gles20/extensions/GUI/CCScrollView/CCScrollView.cpp)
Thanks!

Hi,

I am afraid I haven’t got any solution to this. I just wonder if you happened to find one, because I have exactly the same problem.

Thank you! :slight_smile:

Best regards
Andreas

I ended up not using a scroll view but, if i remember correctly, this code fixed the problem:

CCScrollView* scrollView = CCScrollView::create(CCSizeMake(250, 656), NULL); scrollView->setPosition(CCPointZero); scrollView->setContainer(list); scrollView->setDirection(kCCScrollViewDirectionVertical); scrollView->setContentOffset(ccp(0, list->getContentSize().height)); scrollView->updateInset(); addChild(scrollView);

Thank you, I will try it out tomorrow!

What did you end up using instead of Scroll View? :slight_smile:

It was a design decision, so there was no need for scrolling!

good luck

Unfortunately your solution did not work for me. I actually got it to scroll in the direction I wanted to once, but I didn’t understand why. I think the reason why it is scrolling upside down is due to the fact that the positive direction for Y is downwards. So I tried to set the position of the layer so that it would be on the negative side of Y. I think that is how I got it to work once. I will continue to experiment with this idea.

How are you adding the elements to the scrollable view?

andres blanco wrote:

How are you adding the elements to the scrollable view?

Here is my code:

                ////////////////
        //MENU SETTINGS
        CCMenuItemSprite *menuHeader = CCMenuItemSprite::create( header, header, this, menu_selector(Menu::menu1Callback));
        CCMenuItemSprite *menuGame1 = CCMenuItemSprite::create( game1, game1, this, menu_selector(Menu::menu1Callback));
        CCMenuItemSprite *menuGame2 = CCMenuItemSprite::create( game2, game2, this, menu_selector(Menu::menu1Callback));
        CCMenuItemSprite *menuFooter = CCMenuItemSprite::create( footer, footer, this, menu_selector(Menu::menu1Callback));
        CCMenu* menu = CCMenu::create( menuHeader, menuGame1, menuGame2, menuFooter, NULL );

        menu->alignItemsVerticallyWithPadding( 0 );
        menu->setScale( 0.9f );
        menu->setAnchorPoint( ccp(0,0 ));
        menu->setPosition(  ccp(winSize.width/2, winSize.height/2 ) );
        //this->addChild( menu );

        /////////////////////
        //SCROLL VIEW + LAYER
        CCLayer *layer = CCLayer::create();
        layer->setAnchorPoint( CCPointZero );
        layer->setPosition( CCPointZero );
        layer->addChild( menu );
        layer->setContentSize( CCSizeMake( winSize.width, winSize.height*4 ) );
        layer->setPosition( CCPointZero );

        scrollView = CCScrollView::create();
        scrollView->retain();
        scrollView->setPosition( CCPointZero );
        scrollView->setContainer( layer );
        scrollView->setContentSize( CCSizeMake( layer->getContentSize().width, winSize.height ));
        scrollView->setContentOffset( ccp( 0, layer->getContentSize().height ) );
        scrollView->setDirection( CCScrollViewDirectionVertical );
        this->addChild( scrollView );

Sorry for the late answer and once again thank you. :slight_smile:

You can try initializing the scrollview with a size, in the case of CCScrollView it is not the same as setting the content size afterwards. Something like CCScrollView::create(CCSizeMake(layer->getContentSize().width,winSize.height), NULL);

You can also try scrollView->setViewSize(size);

scrollviews have two sizes, the fixed size that clips the view (the ViewSize) and the content size (the actual size of the view).

andres how did you fix it? I have the same problem using scrollview via cocosbuilder

“`andres blanco":http://www.cocos2d-x.org/users/4507
Refer: “cocos2dx/extensions/GUI/CCScrollView/CCScrollView.cpp”:https://github.com/cocos2d/cocos2d-x/blob/master/extensions/GUI/CCScrollView/CCScrollView.cpp#L354

The answer lies in CCScrollView::minContainerOffset@ and CCScrollView::maxContainerOffset CCScrollViewworks in *OpenGL coordinates* (as opposed *window coordinates*) - values are relative to (left, bottom) with positive Y axis going upwards. Also, keep in mind the scroll view’s positioning and thecontainer are anchored (CCNode::setAnchorPoint) to (left, bottom). When you scroll down (move/pull the content upwards to see content below the cut/clip), you see the content below the bottom edge of the screen but it bounces back the moment you let go of the touch/drag because maxContainerOffset` returns (0, 0) and you’ve just tried to move to a positive content offset.

The (attached) diagram shows the state of the scrollview and the container when they’re created/initialized. This is the state or the coordinates to”think in" when setting up and positioning the child elements and container. The gray rectangle (left, bottom) shows the valid region for scrolling the container. Imagine the container’s anchor point moves inside it.

To see the container scrolled to the top to begin with (what you’d expect when working in window coordinates), set the content offset accordingly (immediately after setting it up). This will give the expected results/behavior.

scrollView~~>setContentOffset), false);
A more complete example is in the edited code below.

<pre>
CCSize winSize = CCDirector::sharedDirector~~>getWinSize;
CCLayer* scrollContainer = CCLayer::create; // Container for the scroll view
scrollContainer~~>setAnchorPoint; // CCScrollView does this too when it’s set as the container.
// Content for the container
CCSprite tallContentA = CCSprite::create;
tallContentA >setPosition);
CCSprite *tallContentB = CCSprite::create;
tallContentB
>setPosition);
scrollContainer~~>addChild;
scrollContainer~~>addChild;
float scrollContainerHeight = tallContentA~~>getContentSize.height + tallContentB~~>getContentSize.height;
scrollContainer~~>setPosition;
scrollContainer~~>setContentSize);
// Set up scroll view
CCScrollView
scrollView = CCScrollView::create;
scrollView~~>setPosition(CCPointZero);
scrollView~~>setDirection;
// ScrollView initializes at the . The container also gets positioned relative to that and goes Y-up.
// Pre-set it to the value CCScrollView::minContainerOffset will return when it’s scrolled to the top
//
scrollView~~>setContentOffset(ccp(0.f, (winSize.height-scrollContainerHeight*1.05f)), false);

addChild(scrollView);

http://stackoverflow.com/a/16194082

Hi Pat,

I still have problems in understanding and would like to clarify. Would you please advice?

I am using cocos2d-x-2.2, including its CCScrollView.

The entire scrollview content should layout like this:

And I expect when first initialized, the green sprite will be shown full screen (my view is 960x1280) and I’ll be able to scroll my moving up to see the pink sprite on the bottom. However, it doesn’t work. My initial view shows the bottom part of the view, and when I scroll up or scroll down, everything disappear (move swiftly to above).

My code is like this:

@
{
// Content for the container
// size: 960x1280
m_pSpriteLongSplash = CCSprite::createWithSpriteFrame(
CCSpriteFrameCache::sharedSpriteFrameCache()>spriteFrameByName
);
m_pSpriteLongSplash
>setPosition(ccp(visibleSize.width / 2.0f, 1856.0f));
m_pLayerScrollContainer~~>addChild;
// size: 640x960
m_pSpriteLongBackground = CCSprite::createWithSpriteFrame~~>spriteFrameByName
);
m_pSpriteLongBackground~~>setPosition);
m_pLayerScrollContainer~~>addChild( m_pSpriteLongBackground );

// size: 466x128
m_pSpriteButtonFirst = CCSprite::createWithSpriteFrame(
CCSpriteFrameCache::sharedSpriteFrameCache()>spriteFrameByName
);
m_pSpriteButtonFirst
>setPosition(ccp(visibleSize.width / 2.0f, 192.0f));
m_pLayerScrollContainer~~>addChild;
// size: 466x128
m_pSpriteButtonSecond = CCSprite::createWithSpriteFrame~~>spriteFrameByName
);
m_pSpriteButtonSecond~~>setPosition);
m_pLayerScrollContainer~~>addChild(m_pSpriteButtonSecond);

m_pLayerScrollContainer~~>setContentSize);
}
FLOAT fContentHeight = m_pLayerScrollContainer~~>getContentSize().height;

m_pViewScroll = CCScrollView::create(windowSize, m_pLayerScrollContainer);
m_pViewScroll~~>setPosition;
m_pViewScroll~~>setDirection(kCCScrollViewDirectionVertical);
m_pViewScroll~~>setContentSize);
this~~>addChild( m_pViewScroll );
@

Hi NB SG
On a side note, you might be missing

m_pLayerScrollContainer~~>setPosition;
right after
FLOAT fContentHeight = m_pLayerScrollContainer~~>getContentSize().height;

But perhaps that’s just missing in what you’ve posted on the forum and exists in the complete code.

More importantly, the example code you’ve posted seems to be missing the part which will “scroll down” the container to the position one would expect in window coordinate based UIs (see code lines 21 to 24 in my post above which explain this).
Add:

m_pViewScroll~~>setContentOffset), false);
You seem to have used setContentSize instead of setContentOffset. Remove:
m_pViewScroll~~>setContentSize(ccp(windowSize.width, windowSize.height-2496.0f));

scrollView->setDirection( CCScrollViewDirectionVertical );
scrollView->setDirection( kCCScrollViewDirectionVertical );