CCScrollView does't receive touches (Cocos2d V 3.0) - ios

I try to add CCScrollView with paging (cocos2d- iphone v3.0). But it's not working.
It doesn't call any delegate methods (for example scrollViewDidScroll:).
CCNode *cards = [CCNode node];
for (int i = 0 ; i < 3; i++) {
CCLabelTTF *label = [CCLabelTTF labelWithString:[NSString stringWithFormat:#"label %d", i] fontName:#"Arial" fontSize:24];
label.color = [CCColor redColor];
label.position = ccp(winSize.width * i + winSize.width * 0.5 , winSize.height * 0.5);
[cards addChild:label];
}
self.scrollView = [[CCScrollView alloc] initWithContentNode:cards];
self.scrollView.contentSizeType = CCSizeTypeNormalized;
self.scrollView.contentSize = CGSizeMake(3, 1);
self.scrollView.pagingEnabled = YES;
self.scrollView.delegate = self;
self.scrollView.position = CGPointZero;
self.scrollView.anchorPoint = CGPointZero;
[self addChild:self.scrollView];

You actually need to set the contentSize of the contentNode of the scrollView as opposed to the contentSize of the scrollView.
In CCScrollView.h
#property (nonatomic,strong) CCNode* contentNode;
So you should replace this part of the code:
self.scrollView.contentSizeType = CCSizeTypeNormalized;
self.scrollView.contentSize = CGSizeMake(3, 1);
With this:
self.scrollView.contentNode.contentSizeType = CCSizeTypeNormalized;
self.scrollView.contentNode.contentSize = CGSizeMake(3, 1);

Related

How change the page control indicator on image slide inside scrollview using NSTimer

Here is the image slider which works fine. When dragging manually the image changes and indicator also changes but when i add animation only image changes automatically not the indicator.
Instead of animating image i want to scroll image so that indicators change
just like it changes on dragging. Also i want to add timer to it.
#implementation DashboardViewController {
NSArray * animationArray;
}
#synthesize scroller = scroller;
#synthesize pageControl = pageControl;
-
(void) viewDidLoad {
[super viewDidLoad];
scroller.pagingEnabled = YES;
scroller.showsHorizontalScrollIndicator = NO;
scroller.delegate = self;
animationArray = [NSArray arrayWithObjects: [UIImage imageNamed: # "image1.jpg"],
[UIImage imageNamed: # "image2.jpg"],
[UIImage imageNamed: # "image3.jpg"],
[UIImage imageNamed: # "image4.png"],
[UIImage imageNamed: # "image5.jpg"],
nil
];
CGRect scrollFrame = CGRectMake(0, 0, self.view.frame.size.width, self.scroller.frame.size.height);
scroller.frame = scrollFrame;
self.scroller.contentSize = CGSizeMake(self.scroller.frame.size.width * animationArray.count, self.scroller.frame.size.height);
for (int i = 0; i < animationArray.count; i++) {
CGRect frame;
frame.origin.x = self.scroller.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scroller.frame.size;
UIImageView * imgView = [
[UIImageView alloc] initWithFrame: CGRectMake(self.scroller.frame.size.width * i, 0, self.scroller.frame.size.width, self.scroller.frame.size.height)
];
imgView.image = [animationArray objectAtIndex: i];
imgView.frame = frame;
imgView.animationImages = animationArray;
imgView.animationDuration = 8;
imgView.animationRepeatCount = 0;
[imgView startAnimating];
[self.scroller addSubview:imgView];
}
self.pageControl.currentPage = 0;
}
-
(void) scrollViewDidScroll: (UIScrollView * ) sender {
if (!pageControlBeingUsed) {
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scroller.frame.size.width;
int page = floor((self.scroller.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
} -
(void) scrollViewWillBeginDragging: (UIScrollView * ) scrollView {
pageControlBeingUsed = NO;
}
-
(void) scrollViewDidEndDecelerating: (UIScrollView * ) scrollView {
[self setIndiactorForCurrentPage];
} -
(void) setIndiactorForCurrentPage {
uint page = scroller.contentOffset.x / scroller.frame.size.width;
[pageControl setCurrentPage: page];
}
-
(IBAction) changePage {
// Update the scroll view to the appropriate page
CGRect frame;
pageControl.currentPage = animationArray.count;
frame.origin.x = self.scroller.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scroller.frame.size;
[self.scroller scrollRectToVisible: frame animated: YES];
pageControlBeingUsed = YES;
}
-
(void) didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
self.scroller = nil;
self.pageControl = nil;
}
Instead of animating image i want to scroll image so that indicators change
just like it changes on dragging. Also i want to add timer to it.
I think you have to set your current page inside your for loop for automatic change pagecontrol with image.
//move this up
self.pageControl.currentPage = 0;
for (int i = 0; i < animationArray.count; i++) {
CGRect frame;
frame.origin.x = self.scroller.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scroller.frame.size;
UIImageView * imgView = [
[UIImageView alloc] initWithFrame: CGRectMake(self.scroller.frame.size.width * i, 0, self.scroller.frame.size.width, self.scroller.frame.size.height)
];
imgView.image = [animationArray objectAtIndex: i];
imgView.frame = frame;
imgView.animationImages = animationArray;
imgView.animationDuration = 8;
imgView.animationRepeatCount = 0;
[imgView startAnimating];
self.pageControl.currentPage = i; //set i to current page
[self.scroller addSubview:imgView];
}

How to create buttons around circle with some radius

i try to create programmatically a number of buttons. I what that buttons will created around the circle like on image 1. Now i have some results, i can rotate buttons, but don't know how to set offset between them. Now i have this result: image 2 Here is my code. And thanks for any help!
viewDidload in ViewController
CGPoint point = self.view.center;
NSArray *arrayWithImages = #[#"red", #"pink", #"green", #"blue", #"purple", #"orange", #"yellow"];
NSArray *arrayWithAngle = #[#(0), #(M_PI / 3.8f), #(M_PI / 1.8), #(M_PI / -6), #(M_PI / 6), #(M_PI / -1.8), #(M_PI / -3.8)];
NSMutableArray *arrayWithPlacePoint = [self generatePointForRound:point andAngle:arrayWithAngle andRadius:25.0f];
NSLog(#"array with place point = %#", arrayWithPlacePoint);
for (NSInteger i = 0; i < [arrayWithImages count]; i++) {
PetalObject *petal = [[PetalObject alloc] initWithImageName:arrayWithImages andRotation:arrayWithAngle andIndex:i andPointsArray:arrayWithPlacePoint andCentrPoint:point];
[self.view addSubview:petal.petalButton];
}
I try to generate some x,y point which should be a creation point of each new button
- (NSMutableArray *)generatePointForRound:(CGPoint )centrPoint andAngle:(NSArray *)arrayAngle andRadius:(float)radiusValue {
CGPoint currentPoint;
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0; i < [arrayAngle count]; i++) {
CGFloat x1 = centrPoint.x + (radiusValue * sin([[arrayAngle objectAtIndex:i] doubleValue]));
CGFloat y1 = centrPoint.y + (radiusValue * cos([[arrayAngle objectAtIndex:i] doubleValue]));
currentPoint = CGPointMake(x1, y1);
[array addObject:[NSValue valueWithCGPoint:currentPoint]];
}
return array;
}
And here is my PetalObject in which i create my buttons
-(id)initWithImageName:(NSArray *)imageNameArray andRotation:(NSArray *)angleArray andIndex:(NSInteger )index andPointsArray:(NSMutableArray *)pointsArray andCentrPoint:(CGPoint )centerPoint {
self.isRecorded = NO;
self.isComplited = NO;
UIImage *image = [UIImage imageNamed:imageNameArray[index]];
CGPoint point = [[pointsArray objectAtIndex:index] CGPointValue];
self.petalButton = [[UIButton alloc] initWithFrame:CGRectMake(point.x - 43 , point.y - 180, 86, 168)];
//self.petalButton.transform = CGAffineTransformMake(cos(angle),sin(angle),-sin(angle),cos(angle),boundsPoint.x-boundsPoint.x*cos(angle)+boundsPoint.y*sin(angle),boundsPoint.y-boundsPoint.x*sin(angle)-boundsPoint.y*cos(angle));
[self.petalButton setBackgroundImage:image forState:UIControlStateNormal];
CGFloat angle = [[angleArray objectAtIndex:index] floatValue];
[self.petalButton setTransform:CGAffineTransformMakeRotation(angle)];
return self;
}
Image 1:
Image 2:
Screenshot
And code:
- (void)viewDidLoad {
[super viewDidLoad];
for (NSInteger index = 0; index < 6; index ++) {
UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
button.layer.anchorPoint = CGPointMake(-0.5, 0.5);
button.backgroundColor = [UIColor greenColor];
button.center = CGPointMake(self.view.center.x + CGRectGetWidth(button.frame) / 2.0, self.view.center.y);
button.transform = CGAffineTransformMakeRotation(M_PI * 2 * index / 6.0);
[self.view addSubview:button];
}
}
The key point is anchorPoint, you set all the button with same anchorPoint and frame, then apply different transform.

Custom UIPageControl dots are misplaced on load

I have a weird behavior with custom UIPageControl.
I subclassed it and in setCurrentPage method I draw custom dots.
In iOS 6 on load they just miss.
In iOS 7 the dots are misplaced.
In both iOS's dots are being positioned correctly only after I change the slide.
I tried the following methods without success:
[customPageControl updateCurrentPageDisplay];
[customPageControl updateConstraints];
[customPageControl sizeToFit];
[customPageControl.currentPage = 1];
The code:
#implementation ProfilePagesPageControl
#synthesize originalSubviews;
#synthesize dotsHeight;
- (void)setCurrentPage:(NSInteger)page
{
[super setCurrentPage:page];
[self updateDots];
}
- (void)updateDots
{
for (int i = 0; i < self.subviews.count; i++)
{
UIView* dotView = [self.subviews objectAtIndex:i];
for (int j = dotView.subviews.count - 1; j >= 0; j--)
{
UIView *view = [dotView.subviews objectAtIndex:j];
[view removeFromSuperview];
}
int widthForDots = [Utils getDeviceBounds].width - Constraints.Gap * 3;
int effectiveWidth = widthForDots / self.subviews.count - Constraints.Gap;
int effectiveGap = (widthForDots - (effectiveWidth * self.subviews.count) + Constraints.Gap * 3) / self.subviews.count;
int effectiveHeight = dotsHeight;
if (i == self.currentPage)
effectiveHeight = effectiveHeight + 3;
else
effectiveHeight = effectiveHeight - 3;
CGRect dotViewFrame = dotView.frame;
dotViewFrame.origin.x = effectiveWidth * i + Constraints.Gap + effectiveGap * i;
dotViewFrame.origin.y = self.frame.size.height / 2 - effectiveHeight / 2;
dotViewFrame.size.width = effectiveWidth;
dotViewFrame.size.height = effectiveHeight;
dotView.frame = dotViewFrame;
UIView *dotSubView = [[UIView alloc] initWithFrame:CGRectMake(0,
0,
dotView.frame.size.width,
dotView.frame.size.height)];
if (i == self.currentPage)
dotSubView.backgroundColor = [UIColor blackColor];
else
dotSubView.backgroundColor = [UIColor grayColor];
[UIUtils roundCorner:(UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight) forView:dotSubView];
ProfileSlideView *slideView = [self.originalSubviews objectAtIndex:i];
RevUILabel *label = [[RevUILabel alloc] initWithSize:13];
label.text = slideView.name;
label.frame = CGRectMake(dotSubView.frame.size.width / 2 - label.frame.size.width / 2,
dotSubView.frame.size.height / 2 - label.frame.size.height / 2,
label.frame.size.width,
label.frame.size.height);
[dotSubView addSubview:label];
[dotView addSubview:dotSubView];
}
}
#end
The iOS7 look:
The iOS6 look:
:
After slide look:
Make sure you call updateDots somewhere else (such as viewDidLoad, or viewWillAppear) so they can be set up before you switch any pages. If you only call updateDots in setCurrentPage it will only be called once you switch the page the first time.

UIImageView is cut off on right side within PageControl after zooming

my image is cut off on the right side after zooming in. if i don't set the offset with cgrect make, then it is not cut off, but i want my image to be centered on the screen. how can i have my image centered and not cut off the right portion after zooming?
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor grayColor];
UIScrollView *mainScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
mainScrollView.pagingEnabled = YES;
mainScrollView.showsHorizontalScrollIndicator = NO;
mainScrollView.showsVerticalScrollIndicator = NO;
CGRect innerScrollFrame = mainScrollView.bounds;
for (NSInteger i = 0; i < 2; i++) {
UIImageView *imageForZooming = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"page%d", i + 1]]];
imageForZooming.tag = VIEW_FOR_ZOOM_TAG;
imageForZooming.frame = CGRectMake(50, 0, imageForZooming.bounds.size.width, imageForZooming.bounds.size.height);
UIScrollView *pageScrollView = [[UIScrollView alloc] initWithFrame:innerScrollFrame];
pageScrollView.minimumZoomScale = 0.5f;
pageScrollView.maximumZoomScale = 1.0f;
pageScrollView.contentSize = imageForZooming.bounds.size;
pageScrollView.delegate = self;
[pageScrollView addSubview:imageForZooming];
[mainScrollView addSubview:pageScrollView];
if (i < 1) {
innerScrollFrame.origin.x += innerScrollFrame.size.width;
}
pageScrollView.zoomScale = 0.5f;
}
mainScrollView.contentSize = CGSizeMake(innerScrollFrame.origin.x + innerScrollFrame.size.width, mainScrollView.bounds.size.height);
[self.view addSubview:mainScrollView];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return [scrollView viewWithTag:VIEW_FOR_ZOOM_TAG];
}
EDIT: here is my view hierarchy
View
mainScrollView
innerScrollFrame
pageScrollView
imageForZooming
innerScrollFrame
pageScrollView
imageForZooming
For anyone else having the same problem in the future, what I did was add the following UIScrollViewDelegate protocol:
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
UIView *subView = [scrollView.subviews objectAtIndex:0];
CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width) ? (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height) ? (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
subView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
scrollView.contentSize.height * 0.5 + offsetY);
}
i found the answer here: Center content of UIScrollView when smaller
so that the image would be centered after zooming instead of applying the offset that was initially applied. worked like a charm. now when I zoom, none of my image is cut off on either page control, and I can center the image at the beginning of the view.

Cocos2D - Adding holes and different heights between buildings

I'm trying to build something similar to Canabalt, adding holes and different heights between buildings (modules). You can see a screenshot of how the game is looking right now at: http://twitpic.com/4kb5jd
Here is the code I'm currently using:
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {
moduleSize = 160;
screenSize = [[CCDirector sharedDirector] winSize];
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
[frameCache addSpriteFramesWithFile:#"ModulesScene1.plist"];
CCTexture2D* gameArtTexture = [[CCTextureCache sharedTextureCache] addImage:#"ModulesScene1.png"];
// Create the background spritebatch
spriteBatch = [CCSpriteBatchNode batchNodeWithTexture:gameArtTexture];
[self addChild:spriteBatch];
numStripes = 1;
/* BEGIN MODULES */
NSString* frameName = [NSString stringWithFormat:#"Module0-hd.png"];
CCSprite* sprite = [CCSprite spriteWithSpriteFrameName:frameName];
sprite.anchorPoint = CGPointMake(0, 0.5f);
sprite.position = CGPointMake(0, screenSize.height / 2);
[spriteBatch addChild:sprite z:0 tag:0];
frameName = [NSString stringWithFormat:#"Module0-hd.png"];
sprite = [CCSprite spriteWithSpriteFrameName:frameName];
sprite.anchorPoint = CGPointMake(0, 0.5f);
sprite.position = CGPointMake((moduleSize - 1.1f), screenSize.height / 2);
[spriteBatch addChild:sprite z:1 tag:1];
frameName = [NSString stringWithFormat:#"Module1-hd.png"];
sprite = [CCSprite spriteWithSpriteFrameName:frameName];
sprite.anchorPoint = CGPointMake(0, 0.5f);
sprite.position = CGPointMake((moduleSize * 2) - 1.1f, screenSize.height / 2);
[spriteBatch addChild:sprite z:2 tag:2];
frameName = [NSString stringWithFormat:#"Module2-hd.png"];
sprite = [CCSprite spriteWithSpriteFrameName:frameName];
sprite.anchorPoint = CGPointMake(0, 0.5f);
sprite.position = CGPointMake(((moduleSize * 3) - 1.1f), screenSize.height / 2);
[spriteBatch addChild:sprite z:3 tag:3];
frameName = [NSString stringWithFormat:#"Module0-hd.png"];
sprite = [CCSprite spriteWithSpriteFrameName:frameName];
sprite.anchorPoint = CGPointMake(0, 0.5f);
sprite.position = CGPointMake(((moduleSize * 4) - 1.1f), screenSize.height / 2);
[spriteBatch addChild:sprite z:4 tag:4];
frameName = [NSString stringWithFormat:#"Module1-hd.png"];
sprite = [CCSprite spriteWithSpriteFrameName:frameName];
sprite.anchorPoint = CGPointMake(0, 0.5f);
sprite.position = CGPointMake(((moduleSize * 5) - 1.1f), screenSize.height / 2);
[spriteBatch addChild:sprite z:5 tag:5];
/* END MODULES */
// Get current scrollSpped
scrollSpeed = [[GameManager sharedGameManager] scrollSpeed];
speedFactors = [[CCArray alloc] initWithCapacity:numStripes];
[speedFactors addObject:[NSNumber numberWithFloat:2.5f]];
NSAssert([speedFactors count] == numStripes, #"speedFactors count does not match numStripes!");
[self scheduleUpdate];
}
return self;
}
-(void) update:(ccTime)delta
{
CCSprite* sprite;
scrollSpeed = [[GameManager sharedGameManager] scrollSpeed];
CCARRAY_FOREACH([spriteBatch children], sprite)
{
NSNumber* factor = [speedFactors objectAtIndex:0];
CGPoint pos = sprite.position;
pos.x -= scrollSpeed * [factor floatValue];
if (pos.x < -screenSize.width)
{
pos.x += ((screenSize.width * 2) - 2);
int x = (arc4random() % 3);
int xHole = (arc4random() % 10);
NSString *randomName = nil;
CCSpriteFrame *randomFrame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:randomName];
[sprite setDisplayFrame:randomFrame];
}
sprite.position = pos;
}
}
to add holes between the buildings you could add a simple rand() function like that in the init method:
...
sprite.position = CGPointMake(((moduleSize * 3) - 1.1f + (rand()%40)), screenSize.height / 2);
...
this will add a random gap (max 40 points)

Resources