here is what I wanna do http://www.youtube.com/watch?v=rD3MTTPaK98
and here is my code:
-(void) onTimer {
UIImage * image = [UIImage imageNamed:#"abouffer_03.png"];
imageView = [[UIImageView alloc] initWithImage:image];
[imageView setCenter:[self randomPointSquare]];
[imageViewArray addObject:imageView];
[[self view] addSubview:imageView];
[imageView release];
ix=imageView.center.x;
iy=imageView.center.y;
X=(240-ix)/230;
Y=(160-iy)/230;
coteA=(240-ix);
coteB=(160-iy);
angleDeRotation=atan(coteB/coteA);
if(ix>250||0>iy>320){
imageView.transform = CGAffineTransformMakeRotation(angleDeRotation+3.14);
}
else{
imageView.transform = CGAffineTransformMakeRotation(angleDeRotation);
}
}
-(void)onTimer2{
for(int i=0; i< [imageViewArray count];i++){
imageView = [imageViewArray objectAtIndex:i];
imageView.center = CGPointMake(imageView.center.x + X, imageView.center.y + Y);
}
onTimer is called every 2 seconds
but it doesn't work, there is no error but when a "imageView" is created after 2 seconds it sop moving and go to the same direction of the new " imageView" that has been created. How can I solve this ? sorry for my english I'm french :/
You’re adding X and Y to all of your image views, but it’a always the last-computed value. Make an array of X and Y values and use the value that corresponds with your image view.
Where you define imageViewArray, also define xArray and yArray as NSMutableArrays. Then in -onTimer, when you set X and Y, do this:
[xArray addObject:[NSNumber numberWithFloat:X]];
[yArray addObject:[NSNumber numberWithFloat:Y]];
Finally, in -onTimer2, do this:
-(void)onTimer2{
for(int i=0; i< [imageViewArray count];i++) {
float localX = [(NSNumber *)[xArray objectAtIndex:i] floatValue];
float localY = [(NSNumber *)[yArray objectAtIndex:i] floatValue];
imageView = [imageViewArray objectAtIndex:i];
imageView.center = CGPointMake(imageView.center.x + localX, imageView.center.y + localY);
}
That will use the value of X and Y that you set in -onTimer.
Related
I have a word,depending on its length,I create buttons assigning a character from the word randomly.I am presenting the shuffled character button arrangement in a row.Now I would like to sort the positions of those buttons,i.e. 1st to 3rd,3rd to 5th and so on.Please note that the number of buttons are not fixed,they vary depending on word length.Here is the sample code snippet for an understanding of how I create buttons.
-(void)buttonsCreation:(int)noOfButtons
{
NSMutableArray *charactersArray = [NSMutableArray array];
self.wordButtons = [[NSMutableArray alloc]initWithCapacity:30];
BOOL record = NO;
int randomNumber;
self.jumbledWord = [jumbledWord stringByReplacingOccurrencesOfString:#" " withString:#""];
for (int i=0; [charactersArray count] < jumbledWord.length; i++) //Loop for generate different random values
{
randomNumber = arc4random() % jumbledWord.length;//generating random number
if(i==0)
{
[charactersArray addObject:[NSNumber numberWithInt:randomNumber]];
}
else
{
for (int j=0; j<= [charactersArray count]-1; j++)
{
if (randomNumber ==[[charactersArray objectAtIndex:j] intValue])
record = YES;
}
if (record == YES)
record = NO;
else
[charactersArray addObject:[NSNumber numberWithInt:randomNumber]];
}
}
int arrayValue;
float x;
float y;
if ([jumbledWord length]>11)
{
int remainingWordslength = [jumbledWord length]-11;
x = ((475/2) - (38.0 *(11/2.0))) + 8;
y = ((475/2) - (38.0 *(remainingWordslength/2.0))) + 8;
}
else
{
x = ((475/2) - (38.0 *([jumbledWord length]/2.0))) + 8;
}
for(int i=0;i<[jumbledWord length];i++)
{
CGFloat translation = 0.0;
if(i>=0 && i<11)
{
arrayValue = [[charactersArray objectAtIndex:i] intValue];
UIButton *characterButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
characterButton.frame = CGRectMake(x,160.0, 35.0, 35.0);
x = x + 38;
if (jumbledWord.length>=1 && jumbledWord.length<5)
{
translation = (self.view.frame.size.width - characterButton.frame.size.width)+65.0;
}
if (jumbledWord.length>=5 && jumbledWord.length<11)
{
translation = (self.view.frame.size.width - characterButton.frame.size.width)+160.0;
}
characterButton.transform = CGAffineTransformMakeTranslation(translation, 0);
[UIView animateWithDuration:1.30f
delay:0.7
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
characterButton.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
}];
[wordButtons addObject:characterButton];
NSString *characterValue = [NSString stringWithFormat:#"%c",[jumbledWord characterAtIndex:arrayValue]];
[characterButton setTitle:characterValue forState:UIControlStateNormal];
[characterButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
if (arrayValue==0)
{
arrayValue = 100;
}
[characterButton setTag:arrayValue*100];
[self.view addSubview:characterButton];
}
else if(i>=11 && i<20)
{
arrayValue = [[charactersArray objectAtIndex:i] intValue];
UIButton *characterButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
characterButton.frame = CGRectMake(y,200.0, 35.0, 35.0);
y = y + 38;
if (jumbledWord.length>=11 && jumbledWord.length<15)
{
translation = (self.view.frame.size.width - characterButton.frame.size.width)+70.0;
}
if (jumbledWord.length>=15 && jumbledWord.length<=20)
{
translation = (self.view.frame.size.width - characterButton.frame.size.width)+150.0;
}
characterButton.transform = CGAffineTransformMakeTranslation(translation, 0);
[UIView animateWithDuration:1.30f
delay:0.7
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
characterButton.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
}];
[wordButtons addObject:characterButton];
NSString *characterValue = [NSString stringWithFormat:#"%c",[jumbledWord characterAtIndex:arrayValue]];
[characterButton setTitle:characterValue forState:UIControlStateNormal];
[characterButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
if (arrayValue==0)
{
arrayValue = 100;
}
[characterButton setTag:arrayValue*100];
[self.view addSubview:characterButton];
}
}
}
I do acknowledge the ideal choice would be to assign the frame i.e. "x" positions for buttons,but how do I do this.The other option being exchanging the index positions and I tried it too,i.e.:
-(void)shuffleButtons
{
for (UIButton *characterButton in wordButtons)
{
id sortObject1 = [self.wordButtons objectAtIndex:0];
id sortObject1 = [self.wordButtons objectAtIndex:1];
id sortObject1 = [self.wordButtons objectAtIndex:2];
[self.wordButtons removeObjectAtIndex:0];
[self.wordButtons removeObjectAtIndex:1];
[self.wordButtons insertObject:characterButton atIndex:1];
[self.wordButtons insertObject:characterButton atIndex:0];
[self.wordButtons removeObjectAtIndex:2];
[self.wordButtons insertObject:characterButton atIndex:1];
}
}
OOPS and it crashes,any one please guide me a way.I need to accomplish because there is an option for user to shuffle the jumbled arrangement of a word.
Thanks in advance :)
I've already developed a sample project for this.
Take a look at DragME source over github.
Since we are having all the buttons in wordButtons array,we can make use of those index locations and exchange their places with a little animation ;) ,i.e.
- (void)exchangeButtons
{
UIButton *firstButton = self.wordButtons[0];
UIButton *lastButton = self.wordButtons[self.wordButtons.count - 1];
UIButton *secondButton = self.wordButtons[1];
UIButton *thirdButton = self.wordButtons[2];
[self exchangeButton:firstButton withAnother:lastButton];
[self exchangeButton:secondButton withAnother:thirdButton];
}
//Animate buttons while interchanging positions
- (void)exchangeButton:(UIButton *)firstButton withAnother:(UIButton *)secondButton
{
CGRect firstButtonFrame = firstButton.frame; [UIView animateWithDuration:1.0f animations:^{ firstButton.frame = secondButton.frame; secondButton.frame = firstButtonFrame; }];
}
Please note that the exchange button code may vary,it all depends on the length of word i.e. number of buttons.So you may place conditions like if(wordButtons.count >= 6) or >=10 etc. before you exchange the button indices.
P.S. -- A more effective and non-hard coded solution
Let's store the frame of the button while creating a row of buttons and use that to interchange the button positions i.e. while creation assign our button frame to declared CGRect object,i.e.
CGRect originalFrameArray[16]; --> **Global variable**
originalFrameArray[i] = characterButton.frame;
Now let's create 2 arrays,one for shuffling the word and storing the character buttons indices,other for modifying the buttons array and then start exchanging the buttons with little animation :)
- (void)exchangeButtons
{
NSMutableArray *charactersArray = [NSMutableArray array];
NSMutableArray *copyOfButtons = [NSMutableArray arrayWithArray:wordButtons];
BOOL record = NO;
int randomNumber;
for (int i=0; [charactersArray count] < jumbledWord.length; i++) //Loop for generate different random values
{
randomNumber = arc4random() % jumbledWord.length;//generating random number
if(i==0)
{
[charactersArray addObject:[NSNumber numberWithInt:randomNumber]];
}
else
{
for (int j=0; j<= [charactersArray count]-1; j++)
{
if (randomNumber ==[[charactersArray objectAtIndex:j] intValue])
record = YES;
}
if (record == YES)
record = NO;
else
[charactersArray addObject:[NSNumber numberWithInt:randomNumber]];
}
}
int arrayValue;
for(int i=0;i<[jumbledWord length];i++)
{
arrayValue = [[charactersArray objectAtIndex:i] intValue];
[wordButtons replaceObjectAtIndex:arrayValue withObject:[copyOfButtons objectAtIndex:i]];
}
for(int i=0; i < [jumbledWord length]; i++)
{
UIButton *characterButton = [wordButtons objectAtIndex:i];
[self shiftButtonToFrame:characterButton :originalFrameArray[i]];
}
}
//Animate the buttons while they exchange positions
- (void) shiftButtonToFrame:(UIButton *) characterButton :(CGRect) frame
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:1.0];
[characterButton setFrame:frame];
[UIView commitAnimations];
}
Hope it helps some one.Thanks and happy coding :)
How can i dynamically arrange icons(UIButtons, with backgroundImages) in circle image.SOmething like it should like concentric circles.
I am using the following code,
UIImageView *container = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0f, 299.0f, 298.0f)];
container.image = [UIImage imageNamed:#"AR_RF004_circle.png"];
container.center = CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0);
[self.view addSubview:container];
NSArray *imagesArray = [[NSArray alloc]initWithObjects:[UIImage imageNamed:#"AR1.png"],[UIImage imageNamed:#"AR2.png"],[UIImage imageNamed:#"AR3.png"],[UIImage imageNamed:#"AR4.png"],[UIImage imageNamed:#"AR5.png"], nil];
int numberOfSections = 5;
CGFloat angleSize = 2*M_PI/numberOfSections;
for (int j = 0; j < numberOfSections; ++j) {
UIButton *sectionLabel = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 128.0f)];
[sectionLabel setBackgroundImage:[imagesArray objectAtIndex:j] forState:UIControlStateNormal];
sectionLabel.layer.anchorPoint = CGPointMake(0.9f, 0.1f);
sectionLabel.layer.position = CGPointMake(container.bounds.size.width/2.0, container.bounds.size.height/2.0); // places anchorPoint of each label directly in the center of the circle.
sectionLabel.transform = CGAffineTransformMakeRotation(angleSize*j);
[container addSubview:sectionLabel];
NSLog(#"section label x and y is %f ,%f",sectionLabel.frame.origin.x,sectionLabel.frame.origin.y);
}
[container release];
Thanks in Advance
You can use this piece of code:
UIButton *currentButton;
int buttonCount = 20;
int radius = 200;
float angleBetweenButtons = (2 * M_PI) / buttonCount;
float x = 0;
float y = 0;
CGAffineTransform rotationTransform;
for (int i = 0; i < buttonCount; i++)
{
// get your button from array or something
currentButton = ...
...
x = radius + cosf(i * angleBetweenButtons) * radius;
y = radius + sinf(i * angleBetweenButtons) * radius;
rotationTransform = CGAffineTransformIdentity;
rotationTransform = CGAffineTransformRotate(rotationTransform, (i * angleBetweenButtons));
currentButton.center = CGPointMake(x, y);
currentButton.transform = rotationTransform;
}
I think you can do something like this
sectionLabel.center = container.center;
I have not checked other code.. Simplest way for this
The code below is supposed to display a series of images in an infinite, connected loop. Instead, it just displays a totally white field. Thanks to Aaron Hayman for getting me this far.
- (void)layoutScrollImages
{
//Arrangement
NSArray *imageViews = [NSArray arrayWithObjects:#"image1.png", #"image2.png", #"image3.png", nil];
CGRect cRect = scrollView1.bounds;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++)
{
cView = [imageViews objectAtIndex:i];
cView.frame = cRect;
[scrollView1 addSubview:cView];
cRect.origin.x += cRect.size.width;
}
scrollView1.contentSize = CGSizeMake(cRect.origin.x, scrollView1.bounds.size.height);
scrollView1.contentOffset = CGPointMake(scrollView1.bounds.size.width, 0); //should be the center page in a 3 page setup
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
scrollView1.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
}
FOLLOW UP:
Nothing I'm doing is making any difference. Currently, my code looks like this, but I'm changing everything I can think of to no avail.
- (void)layoutScrollImages
{
//Horizontal arrangement
NSObject *image1 = #"image1.png";
NSObject *image2 = #"image2.png";
NSObject *image3 = #"image3.png";
NSArray *imageViews = [NSArray arrayWithObjects:image1, image2, image3, nil];
CGRect cRect = scrollView1.bounds;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++)
{
cView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[imageViews objectAtIndex:i]]];
cView.frame = cRect;
[scrollView1 addSubview:cView];
cRect.origin.x += cRect.size.width;
}
scrollView1.contentSize = CGSizeMake(cRect.origin.x, scrollView1.bounds.size.height);
scrollView1.contentOffset = CGPointMake(scrollView1.bounds.size.width, 0); //should be the center page in a 3 page setup
[self layoutScrollImages];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
scrollView1.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
}
You never initiate a UIImageView. You want to do something like this:
NSArray *imageViews = [NSArray arrayWithObjects:#"image1.png", #"image2.png", #"image3.png", nil];
CGRect cRect;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++)
{
cView = [[UIImageView alloc] initWithImage:[UIImage imageName:[imageViews objectAtIndex:i]]];
cRect = cView.frame;
cRect.origin.x += scrollView1.frame.size.width;
cView.frame = cRect;
[scrollView1 addSubview:cView];
NSLog(#"imageView bounds: %#", NSStringFromCGRect(cView.frame));
}
Edit:
Try the above and see if anything shows up. Here are some thoughts:
Are you sure that you aren't setting the imageView to have 0 height/width? I threw in an NSLog statement to the loop. It will print the frame of the imageView.
Have you tried adding the images to self.view instead of scrollView1? That would be a good way to make sure that the problem doesn't have to do with the frame of scrollView1. Or use the following:
NSLog(#"imageView bounds: %#", NSStringFromCGRect(scrollView1.frame));
I have a sprite on which there is a label (CCLabelTTF). On that label i have A,B,C,D,E, etc printed when they are clicked. I want them to scroll left. I've googled some tuorials but i am unable to find the solution and stuck here for long. Here is the screenshot of my game. You can see the characters from A to J. When i click on more incoming characters, that portion should scroll. What can i do to make the characters scroll?
Here is the code from which the characters are shown on label (lblSelectedAlpha) added on sprite:-
-(void)showSelectedAlphaBet{
fSelectedAlphaY =26;
if (tempBackground) {
[tempBackground removeFromParentAndCleanup:YES];
}
tempBackground = [CCSprite spriteWithFile:#"stripe_2.png"];
tempBackground.position = ccp(160,30);
[self addChild:tempBackground z:30];
for (int i=0; i<[arryAddSelectedChar count]; i++) {
// NSLog(#"[arryAddSelectedChar count] %#",[arryAddSelectedChar objectAtIndex:i]);
lblSelectedAlpha = [CCLabelTTF labelWithString:
[arryAddSelectedChar objectAtIndex:i]dimensions:CGSizeMake(30,30)
alignment:UITextAlignmentCenter fontName:#"Marker Felt" fontSize:30];
lblSelectedAlpha.position = ccp(fSelectedAlphaY,25);
lblSelectedAlpha.tag=i;
lblSelectedAlpha.color = ccc3(125,125,125);
[tempBackground addChild:lblSelectedAlpha z:5];
fSelectedAlphaY +=25;
}
}
Scrolling is simply a constant change in position over time. Basically something like this:
-(void) update:(ccTime)delta
{
label.position = CGPointMake(label.position.x - 1, label.position.y);
}
Well, this is how i implemented scrolling in my cocos2d game
// How to add scroll on label. This i did with a UITextView
// inside init, i took
{
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(10,430, 150, 50)]
alphabetScroll = [[UITextView alloc] initWithFrame:CGRectMake(10,0,50 ,50)];
alphabetScroll.font = [UIFont fontWithName:#"verdana" size:30.0f];
alphabetScroll.backgroundColor = [UIColor clearColor];
alphabetScroll.textColor = [UIColor colorWithRed:125.0/255.0 green:125.0/255.0 blue:125.0/255.0 alpha:1.0f];
alphabetScroll.userInteractionEnabled=NO;
[scroll addSubview:alphabetScroll];
[[[CCDirector sharedDirector]openGLView]addSubview:scroll];
}
-(void)showSelectedAlphaBet
{
NSLog(#"showSelectedAlphaBet");
fSelectedAlphaY =26; // I have 26 alphabets
if (tempBackground) {
[tempBackground removeFromParentAndCleanup:YES];
}
// Area where alphabets are added on touch
tempBackground = [CCSprite spriteWithFile:#"stripe_2.png"];
tempBackground.position = ccp(160,30);
[self addChild:tempBackground z:30];
bottomAlphabet = #" ";
for (int i=0; i<[arryAddSelectedChar count]; i++) {
NSLog(#"[arryAddSelectedChar count] %#",[arryAddSelectedChar objectAtIndex:i]);
bottomAlphabet = [bottomAlphabet stringByAppendingString:[arryAddSelectedChar objectAtIndex:i]];
}
// Implementing shifting/scrolling
int newScrollViewWidth;
int newLabelWidth;
newScrollViewWidth =25*[arryAddSelectedChar count];
newLabelWidth =50*[arryAddSelectedChar count];
[scroll setContentSize:CGSizeMake(newScrollViewWidth, 45)];
alphabetScroll.frame = CGRectMake(0, 0, newLabelWidth, 45);
alphabetScroll.text = bottomAlphabet;
if (newScrollViewWidth > 150) {
CGPoint svos;
CGPoint pt;
svos = scroll.contentOffset;
CGRect rc = [alphabetScroll bounds];
rc = [alphabetScroll convertRect:rc toView:scroll];
pt = rc.origin;
pt.y = 0;
pt.x += 20*([arryAddSelectedChar count]-5);
[scroll setContentOffset:pt animated:YES];
}
}
// In dealloc
[alphabetScroll release];
I'm trying to dynamically add Images to a ScrollView. Before adding I check if there are any subviews in the ScrollView and delete them in a for loop.
When I release the imageview I get a runtime error stating i'm trying to acces a deallocated instance. If I remove the release statement the application will run correctly but "build and analyze" shows a leak because th reference count of imageview is not decreased..
if ([scrollView.subviews count]>0){
for (int i=0; i<[scrollView.subviews count]; ++i) {
[[scrollView.subviews objectAtIndex:i] removeFromSuperview];
}
}
//Making a scroller with results
int scrollWidth = 0.0f;
int scrollHeight = 0.0f;
for (int i = 0; i<previewImages.count;++i)
{
UIImage *image=[previewImages objectAtIndex:i];
scrollWidth = scrollWidth + image.size.width; // Width of all the images
if (image.size.height > scrollHeight)scrollHeight= image.size.height; // Maximum image height
[image release];
}
float xC = 0.0f;
for (int i=0; i<previewImages.count; ++i) {
UIImage *image=[previewImages objectAtIndex:i];
UIImageView *imageview = [[UIImageView alloc] initWithFrame:CGRectMake(xC, 0.0f, image.size.width, image.size.height)];
UILabel *subScript = [[UILabel alloc] initWithFrame:CGRectMake(xC, image.size.height-30.0f, image.size.width,30.0f)];
subScript.textColor = [UIColor whiteColor];
subScript.backgroundColor = [UIColor colorWithWhite:0.5f alpha:0.5f];
subScript.text = [imagePaths objectAtIndex:i];
imageview.image = image;
xC = xC + image.size.width;
[image release];
[scrollView addSubview:imageview];
[imageview release];
[scrollView addSubview:subScript];
[subScript release];
}
[scrollView setContentSize:CGSizeMake(scrollWidth , scrollHeight)];
Any suggestions about the memory leak or general best practices for adding and removing views from an array into a scrollView are much appreciated!
if ([scrollView.subviews count]>0){
for (int i=0; i<[scrollView.subviews count]; ++i) {
[[scrollView.subviews objectAtIndex:i] removeFromSuperview];
}
}
is wrong, because you are removing subview from subviews array. Do reverse iteration would fix that, but I would suggest keeping the view in separated array instead.