Cocos2D and UIScrollView

August 21st, 2009 by Rob Segal Leave a reply »

Learning now to work with a new framework is usually a challenge.  You often delve into a new API or SDK expecting things to work in a certain manner.  When those expectations fail you need to delve deeper to find your answer in several different ways.  It often starts with visiting the website of the package you are working with.  This often leads to..

All of these approaches have their pros and cons and I have often found its some combination of these sources that will lead you to your answer.  In my case I have been trying over the past couple of weeks to get Cocos2D working with a UIScrollView container.  This is a requirement for the game we are working on to allow players to get the familiar scrolling movement you see in many iPhone apps.

We tried a number of approaches to get this to work properly…

  1. Cocos window embedded inside a UIScrollView instance
  2. Changing the size of the OpenGL rendering window to render a larger space.  Works but there is a serious performance hit.
  3. A UIScrollView instance overlaid on top of a Cocos window.  If the scroll movements were caught they could be passed onto the Cocos window manually.

Ultimately we chose option #3 and this is the option I will cover details for in this article as it is ultimately the only solution which worked for us properly.

Modifications to the Cocos source code

The first step to get this to work properly is a small modification to the Cocos source code.  The reason being that Cocos will freeze while working with a UIScrollView by default.  Luckily the location to you need to modify is noticeably documented in the Cocos source code.  In Director.m look for this block of comment with code…

//
// If you want to attach the opengl view into UIScrollView
// uncomment this line to prevent 'freezing'. It doesn't work on
// with the Fast Director
//
// [[NSRunLoop currentRunLoop] addTimer:animationTimerforMode:NSRunLoopCommonModes];

Simply uncomment this line of code to get freeze free scrolling.  Leave the lines commented out to see the difference in movement as my description may not make it readily apparent.

Using a view controller and a UIScrollView together

Detecting touches in UIScrollView

One of the necessary steps to getting this to work properly would be to detect both touches and swipes in the UIScrollView instance and pass those messages along to the Cocos window.  Researching this in Google revealed the following forum posting which was a huge help.  The solution there is to use a UIViewController where the view in that controller is an instance of UIScrollView.  Here’s what that setup looks like in our codebase…

CocosOverlayViewController.h

#import 
 
@interface CocosOverlayViewController : UIViewController
{
}
@end

CocosOverlayViewController.m

#import "CocosOverlayViewController.h"
#import "CocosOverlayScrollView.h"
 
@implementation CocosOverlayViewController
 
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
  CocosOverlayScrollView *scrollView = [[CocosOverlayScrollView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
 
  // NOTE - I have hardcoded the size to 1024x1024 as that is the size of the levels in
  // our game.  Ideally this value would be parameterized or configurable.
  //
  scrollView.contentSize = CGSizeMake(1024, 1024);
 
  scrollView.delegate = scrollView;
  [scrollView setUserInteractionEnabled:TRUE];
  [scrollView setScrollEnabled:TRUE];
 
  self.view = scrollView;
 
  [scrollView release];
}
@end

CocosOverlayScrollView.h

#import 
 
@interface CocosOverlayScrollView : UIScrollView
{
}
@end

CocosOverlayScrollView.m

#import "CocosOverlayScrollView.h"
#import "cocos2d.h"
 
@implementation CocosOverlayScrollView
 
-(void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{
  if (!self.dragging)
  {
    UITouch* touch = [[touches allObjects] objectAtIndex:0];
    CGPoint location = [touch locationInView: [touch view]];
 
    [self.nextResponder touchesBegan: touches withEvent:event];
    [[[Director sharedDirector] openGLView] touchesBegan:touches withEvent:event];
  }
 
  [super touchesBegan: touches withEvent: event];
}
 
-(void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event
{
  if (!self.dragging)
  {
    [self.nextResponder touchesEnded: touches withEvent:event];
    [[[Director sharedDirector] openGLView] touchesEnded:touches withEvent:event];
  }
 
  [super touchesEnded: touches withEvent: event];
}
 
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
  // TODO - Custom code for handling deceleration of the scroll view
}
 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
  CGPoint dragPt = [scrollView contentOffset];
 
  Scene* currentScene = [[Director sharedDirector] runningScene];
 
  // Only take the top layer to modify but other layers could be retrieved as well
  //
  Layer* topLayer = (Layer *)[currentScene.children objectAtIndex:0];
 
  dragPt = [[Director sharedDirector] convertCoordinate:dragPt];
 
  dragPt.y = dragPt.y * -1;
  dragPt.x = dragPt.x * -1;
 
  CGPoint newLayerPosition = CGPointMake(dragPt.x + (scrollView.contentSize.height * 0.5f), dragPt.y + (scrollView.contentSize.width * 0.5f));
 
  [topLayer setPosition:newLayerPosition];
}
 
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
  CGPoint dragPt = [scrollView contentOffset];
 
}
@end

This is by no means a perfect solution yet as I still have some values hardcoded such as the size of the content for the scroll view window. I will certainly be working to improve the finer points but hopefully the core issues I’ve put together will be useful to some of you.  Our next dev video (when we get it posted) will show the scroll view in action.

  • orochi
    Hello, I did it and worked.

    The only problem is when I create another thread with:

    [NSThread detachNewThreadSelector:@selector(someSelector:) toTarget:self withObject:extraParams];

    The CocosNode freezes!

    What could be do to solve this problem?
  • orochi
    "What could be do to solve this problem?"

    I'm sorry that was not the right question. The right one is:

    The creation of a NSThread can influence somehow the cocos2d Director?

    I tryed to update the code with the answeres on this post, but anything worked.

    The NSThred is used to handle NetWork events, but the Graphical interface and the UIScrollView is the same thread. This object and the GUI is not called anywhere in the second thread.

    The simple creation of a new NSThread makes the UIScrollView to freeze.
  • Unfortunately I haven't played around too much with spawning other threads and Cocos2D. Do you really need to spawn a new thread for the work you are doing? If you post some of the details of your needs maybe we can come up with an alternative solution to your problem.
  • orochi
    I really need, the game network, I believe, it must run in another thread. I don't know another way to make a network without put another thread.

    But I'm not sending and receiving anything by now. I just create another thread with NSThread. Try to do this and you'll see the problem when scrolling:

    - (void)someFunction
    {
    printf("Just printing this in another thread\n");
    }

    - (void)initAThread
    {
    [NSThread detachNewThreadSelector:@selector(someFunction:) toTarget:self withObject:extraParams]
    }

    For me there is no sense on this. Maybe there are some specific stuff of NSRunLoop interaction with NSThreads.
  • I don't recall the specific API calls and/or package names but Cocos2D does have a multiplayer/networking framework built into it. You should definitely check that out. Failing that there is likely some third party middleware to handle this functionality. Let me know if you can't find anything though.
  • colinator
    Is this supposed to scroll the underlying layer in real-time? I'm not seeing it. What I see is that I can scroll, but the underlying layer, or whatever I'm modifying the position of, doesn't actually change its position until I mouse/finger up, or until deceleration is finished, finishing the scroll action. I thought it might be related to that first thing (uncomment that line), but that line never gets called anyway...
  • Ok I think I have tracked down the source of this issue. I will update the article to reflect the details but the core of it comes down to setting the Director type properly when you are first making use of it.

    In the HelloWorld sample you'll notice the following lines of code at the beginning of the applicationDidFinishLaunching callback...

    // Try to use CADisplayLink director
    // if it fails (SDK < 3.1) use Threaded director
    if( ! [Director setDirectorType:CCDirectorTypeDisplayLink] )
    [Director setDirectorType:CCDirectorTypeDefault];

    If you comment these lines out you should now get the real time scrolling effect. The reason has to do with how Cocos initializes itself based on the use of the setDirectorType method and how scrolling is able to work. If you want the full details I can review here but I figure its better just to update the article. Colinator and Damian if you could both try this out and let me know how things turn out it I would most appreciate it.
  • Damian
    Still the same problem, however I've been modifying that code a bit, essentially adding "scrollView" to "window" as a subview, here's the modified the code:

    // before creating any layer, set the landscape mode
    [[Director sharedDirector] setDeviceOrientation:CCDeviceOrientationLandscapeLeft];
    [[Director sharedDirector] setAnimationInterval:1.0/60];
    [[Director sharedDirector] setDisplayFPS:YES];

    CocosOverlayScrollView* scrollView = [[CocosOverlayScrollView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
    scrollView.contentSize = CGSizeMake(320, 960);

    [scrollView setUserInteractionEnabled:TRUE];
    [scrollView setScrollEnabled:TRUE];

    [window addSubview:scrollView];

    // create an openGL view inside a window
    [[Director sharedDirector] attachInView:scrollView];
    [window makeKeyAndVisible];

    [[Director sharedDirector] runWithScene: [HelloWorld scene]];

    Now although the scene does stop for a moment when scrolling, you can still see the smooth scrolling movement once you lift up your finger, before the movement was jerky, kinda like jumping from one frame to another.

    However if I do comment the lines you mentioned Rob, that is no longer the case, only the scrolling movement is not as smooth as when they are not commented, not sure why?
  • Hi Damian sorry I haven't gotten back to you over the past couple of days. I think I got you for most of the details you covered. On this point though...

    "However if I do comment the lines you mentioned Rob, that is no longer the case, only the scrolling movement is not as smooth as when they are not commented, not sure why?"

    You're saying that when you don't comment out the two lines I mentioned the scrolling is smoother than when they are commented? I'll try out your code to see if I can pickup on anything.
  • Damian
    No worries Rob, I appreciate the time you're giving to help out here.

    Yes, when I don't comment the lines you previously mentioned, scrolling is indeed smoother for some reason, though you get your occasional hiccups. It's like with commenting these lines, the scrolling movement drops a couple frames but never stops, and when leaving these lines, the scrolling movement itself is very smooth, only the scene animation stops for a moment on the very beginning of the scroll movement. It's kinda hard to explain in words, but hopefully you'll see what I mean when testing the code yourself.
  • Hi Damian,

    I have not forgotten about you. I just haven't had that much time to look into this issue over the past couple of days. I was trying out some things just now and found that the scrolling actually works fine for me using the code we've discussed. I'm wondering if you might be able to send me all the code files you've modified when working with the hello world sample. I would guess its just the one file (HelloWorld.m) but if not let me know. Send it to (rob #at# getsetgames.com).
  • Oscar
    Thank you this has worked great on my game!.
    However there is one problem I still haven't figured out a solution for while commenting:
    //if( ! [Director setDirectorType:CCDirectorTypeDisplayLink] )
    //[Director setDirectorType:CCDirectorTypeDefault];
    Does make the uiscrollbar scroll pretty smoothly, sometimes when the application starts 1 out of 5 times it will top at 40 fps and stay there, while usually when my agme starts it will do 60 fps. Apparently riq responded in the cocos2d forums that this has something to do precisely with not using the Director Displaylink type.

    Does anyone else have the same problem?. Any help will be greatly appreciated. Thank you.

    -Oscar
  • Hi Oscar glad the article helped you out. Can't say I've heard anything about this issue but if you post some of your code it might give a better idea of how your trying to set things up and where you might be running into issues. You may also want to try posting on the Stack Overflow community (http://www.stackoverflow.com). There are many people using Cocos2D there.
  • Hi, I am having problems integrating a UIScrollView within a cocos2D layer. Scrolling work's fine, however, when I scroll across the touch event's on my sprite are not registered. If I scroll back to the original position of the UIScrollView it picks up the touch events perfectly. TBH, I'm banging my head against a wall here and I haven't got a clue what to do. Bit of a background on the app: sprites span across three pages, 320*480, they are added dynamically, when a page is filled with sprites it will scroll onto the next one. Thanks in advance :)
  • Sounds like the sprite positions are not being updated along with the movement of the underlying layer. I can't remember if this is done implicitly for you in Cocos2D. Something you could try is scrolling a little bit in one direction and see how that effects touch position. For example if you scroll to the right very slightly does your touch get detected to the left the amount you scrolled to the right? Could be you are get a touch position/sprite position reflection if that makes any sense. Let me know if not.
  • Thanks for all of your help BTW.

    Yes I think you might be on to something, this is the behaviour...

    If I move the UIScrollbar to the left, by the width of the sprite, the sprite will respond to a touch event double its orignal position to the left. Again, if I move the UIScrollbar to the left but this time by half the width of the sprite, the sprite will respond to a touch event double the movement of the UIScrollbar... man, I hope I have explained this correctly :)

    Any ideas?
  • Ok so sounds like its an issue of updating the sprites position while you're scrolling. I don't have the code I used for our games in front of me so I can't tell you off hand if you need to update the sprites on the layer explicitly. When you do the scrolling action do the underlying sprites move in the direction you want?
  • Carl
    Yes, the movement of the sprites if perfect.
  • Ok well I'm not sure which one of these it is but there are several items which get their position changed when you scroll.

    -The layer
    -The UIScrollView area
    -The sprites

    We'll have to figure out which one exactly is not updating correctly perhaps with some log statements. I believe that is how I tracked down my issues with touches and scrolling. Put a print statement when the position changes for each of these different objects and you can see if they are being updated correctly. So when you scroll up and to the left do the other objects do the same thing? Does that make any sense or do you want some help setting that up?
  • Damian
    Yes, that is exactly the problem I outlined above.
  • Damian
    I am trying to have the Hello World example that comes with the Cocos2D SDK scroll, but the scene/framerate freezes when I do a scroll; it does scroll after a couple seconds. I've used the same code presented in this article, of course modifying Director.m as suggested, following are the modifications I did to the app delegate class, just after the runWithScene call:

    [[Director sharedDirector] runWithScene: [HelloWorld scene]];

    scrollView = [[CocosOverlayScrollView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];

    // NOTE - I have hardcoded the size to 1024x1024 as that is the size of the levels in
    // our game. Ideally this value would be parameterized or configurable.
    //
    scrollView.contentSize = CGSizeMake(1024, 1024);

    scrollView.delegate = scrollView;
    [scrollView setUserInteractionEnabled:TRUE];
    [scrollView setScrollEnabled:TRUE];

    // Add Scrollview to cocos2d
    [[[Director sharedDirector] openGLView] addSubview:scrollView];
    [scrollView release];

    I am using the latest version of Cocos2D 0.8.2, am I missing something?
  • Ok I finally got scrolling working with the HellowWorld sample and discovered a few things. You won't see any actual scrolling of the "Hello World" text implicitly with the sample by injecting the code from this tutorial into it. This is because the text is statically created and if you want it to move you need to tell it to move in the scrollViewDidScroll callback. Maybe you already doing that and I just misunderstood. Let me know.

    Another thing to try out to see if smooth scroll movement is actually working properly is to turn on the scroll indicators if you haven't already. In the loadView method of CocosOverlayViewController put in the lines...

    scrollView.showsVerticalScrollIndicator = YES;
    scrollView.showsHorizontalScrollIndicator = YES;

    after the scroll view has been created. Most likely you won't want those in any final product but they are a great way to determine scrolling is at least being detected.
  • Damian
    Hmm, the text is statically created, but it's also part of a layer which in turn is scrolled in your code, I don't see why I would need to move the actual text.

    The scroll indicators are there by default so I do see them. The problem is exactly as colinator described in the post below.
  • Good point about the layer Damian. The search continues then.
  • On the surface everything sounds like it should work fine. I haven't tested any of our games with 0.8.2 so its possible something could be going on there. Let me give that a try and I'll get back to you Damian. You could try testing with 0.8 and 0.8.1 which I know should work fine.
  • tbone
    Rob: Thanks for the great article!

    Does this method work for OS 2.2.1? It works great for me in OS 3.x, but I'm having issues with 2.2.1 and not really sure where to begin looking. The issue I am having is the view does not scroll in OS 2.2.1. I have been trying on a physical 2.2.1 device and the touch none of the UIScrollViewDelegate methods are being called. The view does seem to be loading "correctly". The scrollViewDidScroll method is being fired when the view is first created, but on 2.2.1 for my application I never receive any calls to the scrollViewDidScroll method after it is instantiated. Any ideas? Does this approach work for you on 2.x? Thanks!
  • Hi tbone,

    Your quite welcome for the article glad you found it useful. That is some puzzling behavior. According to Apple dev docs using the UIScrollViewDelegate should be available as of OS 2.0 and you aren't changing any API calls right? Is this the same application you're running across different versions? Just changing the SDK version?

    I'll take a look through my code to see if anything jogs my memory but in the meantime do you happen to have any code of how you have things structured? It always helps to establish some more familiarity with the problem.

    I can't speak to whether this works with 2.x versions as I just started developing with the iPhone SDK when they released 3.0.
  • tbone
    The code is basically exactly as you have it in your sample. My app is compiled using the 3.0 base SDK and has a deploy target specified of 2.2. It has been working great with the two versions I've already released and allows support for 2.2-3.x while enabling/disabling some features that are 3.x specific. I decided to use your article to add a new feature in my newest version and just discovered this issue during play testing on the 2.2.1 device.

    The UIScrollView issue is odd, since that code in my source is exactly the same and there is no conditional switches, it just seems to behave differently when running on the 2.2.1 OS.

    I've been taking Apple's page scroll example code, which works on my 2.2.1 OS device, and then trying to add the OpenGL aspect. If I can get that to work then I'll introduce Cocos2d again.

    The really strange thing is that all of the touches* events fire perfectly on 2.2.1 and 3.x. It's only the scrollViewDidScroll method that is never firing on 2.2.1.

    Have you tested your app that uses this feature on a 2.x device and if so does it work as expected? Thanks again for any insight!
  • tbone
    SOLVED!

    I had to make three changes to my implementation to get this to work on 2.2.x. It works perfectly as you describe in your article with no changes on a 3.x device. This might not be a fix for everyone wanting to support 2.2.x-3.x, but this worked for me and might help someone else.

    1. I had to change:
    CocosOverlayScrollView *scrollView = [[CocosOverlayScrollView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];

    to

    CocosOverlayScrollView *scrollView = [[CocosOverlayScrollView alloc] initWithFrame:CGRectMake(0,0,320,480)];

    In 2.2.x the applicationFrame was (0,20,320,480) with the status bar disabled. I could not get this to work with anything other than (0,0,320,480).

    2. I was creating this view and removing it dynamically for a level selection menu. This was not working so I simply added it in the application delegate and set hidden=TRUE until I needed to show the UIScrollView. There might be another work around to this, but again it worked fine in 3.x to add/remove it as needed and would not work for me in this manner on 2.2.x. There might be another workaround to this that I just don't know at this point.

    3. I was handling touchesMoved in the UISrollViewDelegate to handle resetting some state in my level selection screen. This works great in 3.x, but I had to remove this for 2.2.x to work. I simply reset my level selection screen state as needed in the scrollViewDidScroll method.
  • That is great to hear tbone. Glad you were able to work things out. Your feedback is really useful and I'll definitely be using it to update the article in the future.
  • Marvin
    I'm curious what it was about the first solution (put a Cocos window in a UIScrollWindow) that didn't work. That's the direction I was/am heading in, and it's in researching that solution that brought me to this blog entry.
  • Hi Marvin,

    I'm trying to remember what the issue was there as I am a few weeks removed from the context. The biggest issue we had to deal with and solve was combining scroll swipe movement along with touch detection. From what I researched you can't do that using just a UIScrollView instance. Please someone correct me if I'm wrong. Having said that if you only need swipe scroll movement then the first solution may work for you.
  • Great article. Exactly what I needed to get scrollview working in my cocos2d project. I also liked the last comment by benimaru since it't not always desirable to push a viewcontroller but just adding a scrollview is good enough.

    One comment though. The following line in CocosOverlayScrollView.m doesn't always have to be this way:
    CGPoint newLayerPosition = CGPointMake(dragPt.x + (scrollView.contentSize.height * 0.5f), dragPt.y + (scrollView.contentSize.width * 0.5f));

    Adding half of the content size assumes that the layer that we're dragging is centered in the scrollview. What I found however was that the layer was placed at the origin by default. So I had to remove the additions of contentSize for it to be behave correctly.

    Also, the offsets can change depending on where you place the layer to begin with.
  • Hi Manpreet,

    Thanks for the feedback. I would imagine there are a few things I got wrong and will need to update in the future. Good point about the layer positioning, it certainly does depend on your needs how that is exactly done.
  • benimaru
    Hey Rob,

    Thanks for the tutorial - your code was of great help.

    I was eventually able to get a UIScrollView to do what I wanted to in my cocos2d app. The layer I was scrolling with the UIScrollView had a large cocos menu in it and the touch locations of the menu seem to compress once the layer was scrolled. I resolved the problem by using the location in view coordinates to handle the touches myself.

    I had never added any UIKit objects to cocos2d before so a bit more of an explanation implementing your classes at the beginning would have been useful.

    I only used the CocosOverlayScrollView class and added it when I needed it like this:

    // Init Scrollview
    scrollView = [[CocosOverlayScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    scrollView.contentSize = CGSizeMake(2000, 480);
    scrollView.bounces = NO;
    scrollView.delaysContentTouches = YES;
    scrollView.delegate = scrollView;

    // Add Scrollview to cocos2d
    [[[Director sharedDirector] openGLView] addSubview:scrollView];
    [scrollView release];

    and removed it like this:

    [scrollView removeFromSuperview];

    Still a great tutorial though, thanks so much for sharing.
  • You're quite welcome! I'll work on constantly updating the article as I look into the finer points of using UIKit controls and classes. This functionality was literally the first thing I looked at when working with the iPhone SDK and Cocos 2D. I was pretty pleased with the end result so rather than trying to understand all the intricacies of what was going on I figure I'd get the details out to the community. Glad you were able to get something to work for you.
  • msureka
    Hi, can this be used without using cocos2d?

    Currently while using uiscrollview on top of opengl, it is giving a massive performance hit. Is there a way where I can create a UIScrollview using opengl?

    Thanks!
  • Do you have any metrics to indicate that having UIScrollView on top of opengl is causing a performance hit? I would find it surprising if this was the case as Cocos2D is ultimately opengl.

    As for your question about creating a UIScrollView instance using opengl I suppose you could roll your own solution. We were actually going to do that here at Get Set but luckily this latest solution worked great. I think it would be a big time investment to develop a custom solution.
  • sugool12
    Thanks for helping out Rob.

    i am in landscap view here is code below

    ///////////////////////////
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
    CGPoint dragPt = [scrollView contentOffset];
    int height = vc.scrollView.frame.size.height;

    int old_x = dragPt.x;
    dragPt.x = dragPt.y;
    dragPt.y = (old_x - 320);

    // make sure we take the absolute value of y, since if we didn't
    // y would always be a negative number.
    dragPt.y = abs(dragPt.y);

    dragPt.y = vc.scrollView.frame.size.height + dragPt.y - self.transformAnchor.y;
    dragPt.x = dragPt.x * -1;

    [self setPosition:dragPt];
    }
    //////////
    where self.transformAnchor.y is set to the height of the (the color layer height on which the scroll view is overlapped),,

    The issue that it got me
    1. the horizontal scrolling works but it does not allow to see the layer completely in horizontal direction,
    2. in vertical it reverse the scrolling like moving courser up ends up moving the screen down and vice versa and ends up having a blank area under the layer ,
  • Seems like you are doing alot of calculations on dragPt.x and dragPt.y which I'm not sure you need to be doing. I assume you are trying to get the point the user clicked on coverted to landscape? Please let me know if I am mistaken. There is actually a function in Cocos to convert to landscape or portrait called "convertCoordinate"...

    [[Director sharedDirector] convertCoordinate:location];

    It will take into account whether you are in portrait or landscape view. I think the point after calling convertCoordinate is the one you want to end up with. In which case your function ends up being written as...

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
    CGPoint dragPt = [scrollView contentOffset];
    CGPoint properOrientationPt = [[Director sharedDirector] convertCoordinate:dragPt];

    [self setPosition:properOrientedPt];
    }

    Let me know how that turns out for you.
  • sugool12
    thanks for that ,

    i have overlapped the scroll view to the layer , but i am having the problem with the scroll view content size stuff,
    The width of the content view is set absolutely right(scrolling right in x direction) but the Height is not set correctly, my scroll View end up having a huge blank area under the layer down side and dont allow to scroll the layer upsize though there is a lot of layer area on upside almost 70%,

    I think i scroll view is setting its position/center accroding to the normal view not based on the Cocos2D??

    any help?
  • Not sure I completely follow the issues you are running into but let me see if I understand you correctly.

    - Scrolling is working for you when moving horizontally or from side to side but scrolling vertically is not.

    - Is your application oriented in portrait or landscape mode? If you are in portrait you may have to change some of the code to get scrolling working for you. Trying changing the line where newLayerPosition is set to...

    CGPoint newLayerPosition = CGPointMake(dragPt.x + (scrollView.contentSize.width * 0.5f), dragPt.y + (scrollView.contentSize.height * 0.5f));

    What I've done is just switch the position of contentSize width and height in the calculation. If you're running for portrait and landscape you may have to make further modifications to the code I have in the article.

    - Do you have some sample code I could look at? Paste the contents of any code changes you have made to that appearing in the article. If you haven't changed anything just let me know that.
  • Sorry for the confusion sugool, good catch! TouchLayer is a custom class we are using in the framework for some of our games. I'll modify the sample code to eliminate that usage as it is not really needed. You'll see it in a moment once I edit the article but the modification will be to eliminate this line in scrollViewDidScroll...

    [[TouchLayer sharedTouchLayer] setPosition:dragPt];

    And replace it if needed with any custom code to pass along drag position movements.
  • Changes complete! Should work fine now.
  • sugool12
    [[TouchLayer sharedTouchLayer] setPosition:dragPt]; statment gives error for me

    and wat is TouchLayer.h?? from where i would get ??
  • sugool12
    what is TouchLayer.h??

    for me [[TouchLayer sharedTouchLayer] setPosition:dragPt]; statement is causing error
blog comments powered by Disqus