I'm totally new to iOS development so forgive me if this question is stupid, but its wrecking my head.
I've set myself the task of building a Hangman Game for iPhone. When the game starts I want the letters of the alphabet to randomly populate into 26 UIImageView's that I have already setup in my ViewController.
I have 2 NSMutableArray's setup. One holds the UIImage reference for the Alphabet images and the other is an array of strings containing the names of all the UIImageViews.
What I'm looking to do is run through a for or a while loop and have the images assigned to the UIImageViews.
Here is the code I'm currently using.
- (void)randomizeAlphabet
{
// Code to randomise Letters on start up of the App.
NSMutableArray *alphabet = [[NSMutableArray alloc] initWithObjects:
[UIImage imageNamed:#"A.png"],
[UIImage imageNamed:#"B.png"],
[UIImage imageNamed:#"C.png"],
[UIImage imageNamed:#"D.png"],
[UIImage imageNamed:#"E.png"],
[UIImage imageNamed:#"F.png"],
[UIImage imageNamed:#"G.png"],
[UIImage imageNamed:#"H.png"],
[UIImage imageNamed:#"I.png"],
[UIImage imageNamed:#"J.png"],
[UIImage imageNamed:#"K.png"],
[UIImage imageNamed:#"L.png"],
[UIImage imageNamed:#"M.png"],
[UIImage imageNamed:#"N.png"],
[UIImage imageNamed:#"O.png"],
[UIImage imageNamed:#"P.png"],
[UIImage imageNamed:#"Q.png"],
[UIImage imageNamed:#"R.png"],
[UIImage imageNamed:#"S.png"],
[UIImage imageNamed:#"T.png"],
[UIImage imageNamed:#"U.png"],
[UIImage imageNamed:#"V.png"],
[UIImage imageNamed:#"W.png"],
[UIImage imageNamed:#"X.png"],
[UIImage imageNamed:#"Y.png"],
[UIImage imageNamed:#"Z.png"],
nil];
NSMutableArray *imgViewsAlphabet = [[NSMutableArray alloc] initWithObjects:
#"letterA",
#"letterB",
#"letterC",
#"letterD",
#"letterE",
#"letterF",
#"letterG",
#"letterH",
#"letterI",
#"letterJ",
#"letterK",
#"letterL",
#"letterM",
#"letterN",
#"letterO",
#"letterP",
#"letterQ",
#"letterR",
#"letterS",
#"letterT",
#"letterU",
#"letterV",
#"letterW",
#"letterX",
#"letterY",
#"letterZ"
, nil];
//Randomly assign the letter from the array
while ([alphabet count] > 0 )
{
int index = arc4random_uniform([alphabet count]);
[(UIImageView *)[imgViewsAlphabet objectAtIndex:index] setImage:[alphabet objectAtIndex:index]];
[alphabet removeObjectAtIndex:index];
[imgViewsAlphabet removeObjectAtIndex:index];
}
}
The code above seems fine in Xcode but when it compiles it crashes out.
Any help at all would be greatly appreciated.
Cheers,
TQ
You have 2 arrays, imgViewsAlphabet and alphabet
imgViewsAlphabet is an array of strings.
alphabet is an array of UIImage objects.
This line:
[(UIImageView *)[imgViewsAlphabet objectAtIndex:index]
setImage:[alphabet objectAtIndex:index]];
Is attempting to fetch an object from the imgViewsAlphabet array, and send it a setImage: message.
What kinds of object are in your imgViewsAlphabet array? Do those kind of objects understand the setImage method?
#DuncanC is right. It seems like you're looking to have an array of image views with images chosen in a random, non-repeating way. A good simple approach is to build that array sequentially, then shuffle it:
NSMutableArray *imageViewArray = [NSMutableArray array];
for (char aChar = 'A'; aChar <= 'z'; ++aChar) {
NSString *imageName = [NSString stringWithFormat:#"%c.png", aChar];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[imageViewArray addObject:imageView];
}
Now shuffle it. There are many ways to do this, like the Fisher-Yates algorithm. Here's a high voted SO answer that does it. In a nutshell:
NSUInteger count = [imageViewArray count];
for (NSUInteger i = 0; i < count; ++i) {
NSInteger remainingCount = count - i;
NSInteger exchangeIndex = i + arc4random_uniform(remainingCount);
[imageViewArray exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];
}
This will leave you with an array of UIImageViews whose images are named #"A.png", #"B.png", etc. in randomized order. You'll need to assign these frames and add them as subviews to some view in order to be seen.
Related
I'm using the following piece of code to download image from web and add it to array.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage* myImage = [UIImage imageWithData:
[NSData dataWithContentsOfURL:
[NSURL URLWithString: #"http://tcpm.mrlazyinc.com/files/users/themafia/te/beauty/02.jpg"]]];
recipePhotos = [[NSMutableArray alloc] initWithObjects:myImage, #"2.png", #"3.png", #"4.png", #"5.png", #"6.png", #"6.png", #"8.png", #"9.png", #"10.png", nil];
});
I'm setting the image on to the ui using the following code,
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:[recipePhotos objectAtIndex:indexPath.row]];
During runtime, image is downloaded from the web is not displayed. Is there anything that I'm missing?
what u are doing is using [UIImage imageNamed: ]
but this will access the object of array recipePhotos and the string in each object will be returned.so u dont have images with those names.
Since the object stored in array is an image u should try this
so try doing
recipeImageView.image = [recipePhotos objectAtIndex:indexPath.row]
or
recipeImageView.image = [UIImage imageWithData:[recipePhotos objectAtIndex:indexPath.row]
In the array recipePhotos only the first index contains proper UIImage as it contains full path that is "http://tcpm.mrlazyinc.com/files/users/themafia/te/beauty/02.jpg" (myImage) and other than that only strings without the file path that is http://tcpm.mrlazyinc.com/files/users/themafia/te/beauty/
recipePhotos = [[NSMutableArray alloc] initWithObjects:myImage, #"2.png", #"3.png", #"4.png", #"5.png", #"6.png", #"6.png", #"8.png", #"9.png", #"10.png", nil];
});
Try to NSLog the array recipePhotos
Use SDWebImage Class to set image to the imageview dynamically from web
Import following file to your header file.
#import "UIImageView+WebCache.h"
after importing file try following code.
[self.imgLogo sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[self.dictTemp valueForKey:#"camp_image"]]] placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]];
Download library from below link :-
https://github.com/rs/SDWebImage
In one of the views of my app, i want to display different animations made from a number of jpg images with the following code...
for (i = 0; i <= HighPic; i = i+1) {
[self.imageArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#%i", imageName, i] ofType:#"jpg"]]];
}
float imageCount = [[[self.selfContent objectAtIndex:overPath] valueForKey:#"lastImageNumber"] floatValue]*2-1;
imageView.animationImages = self.imageArray;
[imageView setAnimationRepeatCount:0];
imageView.animationDuration = (imageCount/25);
[imageView startAnimating];
This works fine inside the simulator, but when i run it on my device, the self.imageArray is equal null. If i instead write:
[imageView setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#0", imageName] ofType:#"jpg"]]];
It shows the right picture, even on the device, but just not the animations...
The reason i'm not using the
[self.imageArray addObject:[UIImage imageNamed:[NSString stringWithFormat:#"%#%i", imageName, i]]];
Is because it takes up too much memory...
Thanks in advance!
I fixed the code myself. When i went to the .h file i saw the imageArray was set to weak so i replaced it with strong and that fixed it :)
I am kinda new to Xcode and I am making a program. What I would like to do is when a person gets a score, it will output it on the screen. Example, the person got a score of 132, it would show the score as "132", how would I replace the numbers with an image so instead of using a font, the numbers are showing as an image. I was thinking if there is anyway to use something like this to output the numbers as a picture, but this wouldn't put them in order or it wouldn't work anyway. If anyone can help me, i'd really appreciate it. Thanks!
one = [UIImage imageNamed:#"1.png"]; //Image for the number 1
two = [UIImage imageNamed:#"2.png"]; //Image for the number 2
three = [UIImage imageNamed:#"3.png"]; //Image for the number 3
NSString *score = "132"; //This is the score the user got
if ([score rangeOfString:#"1"].location == NSFound) {
imagescore = one; //If the score contains one, the image adds the image 1
}
if ([score rangeOfString:#"2"].location == NSFound) {
imagescore += two; //If the score contains two, the image adds the image 2
}
if ([score rangeOfString:#"3"].location == NSFound) {
imagescore +=three; //If the score contains two, the image adds the image 3
}
imageView.image = imagescore; //Would change the image to the images of the score in order
Here i made an array of UIImage from your score string:
EDIT: Now i commented out the array making parts and included iMani's solution to merge the images together. Is it now clear?
-(void)calculateScore{
NSString *score = #"132";
UIImage *scroreImage = [UIImage new];
// NSMutableArray *images = [[NSMutableArray alloc]initWithCapacity:score.length];
for (int i = 0; i < score.length; i++) {
// imageName will be #"1", then #"3" and #"2"
NSString *imageName = [[score substringToIndex:i] substringToIndex:1];
// add extension
imageName = [imageName stringByAppendingString:#".png"];
UIImage *image = [UIImage imageNamed:imageName];
//[images addObject:image];
scroreImage = [self concateImageOne:scroreImage withImageTwo:image]
}
}
-(UIImage*)concateImageOne:(UIImage*)image1 withImageTwo:(UIImage*)image2
{
///Merge images together
}
concateImageOne:withImageTwo: selector made by iMani
I can understand little bit. You have number image like 1.png.,2.png,3.png. If score is 132, you want to show image as 1.png + 2.png + 3.png. That want merge this image into one image.
Code for Merge two images..
-(UIImage*)concateImageOne:(UIImage*)image1 withImageTwo:(UIImage*)image2
{
CGSize size = CGSizeMake(image1.size.width, image1.size.height + image2.size.height);
UIGraphicsBeginImageContext(size);
[image1 drawInRect:CGRectMake(0,0,size.width, image1.size.height)];
[image2 drawInRect:CGRectMake(0,image1.size.height,size.width, image2.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}
Now check with condition, and merge images.
if ([score rangeOfString:#"1"].location == NSFound) {
if (!imagescore)
imagescore = one; //If the score contains one, the image adds the image 1
else
imagescore = [self concateImageOne:imagescore withImageTwo:one]
}
As like, merge all image with condition. Finally, recreate imageview and assign image as below.
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, imagescore.size.width, imagescore.size.height)];
imageView.image = imagescore;
You can get list of Image by follow code:
- (NSArray *)imageFromString:(NSString *)scoreString
{
NSMutableArray *scoreImages = [[NSMutableArray alloc] init];
for (int i = 0; i < scoreString.length; i++) {
NSString *imageName = [NSString stringWithFormat:#"%c.png", [scoreString characterAtIndex:i]];
UIImage *image = [UIImage imageNamed:imageName];
[scoreImages addObject:image];
}
return scoreImages;
}
and write a function to show this list image to view
What I did was:
-(void)calculateScore {
int hundred = self.score / 100;
int ten = self.score / 10;
int remainder = self.score % 10;
NSString *hundredString = [NSString stringWithFormat:#"number_%d.png", hundred];
NSString *tenString = [NSString stringWithFormat:#"number_%d.png", ten];
NSString *remainderString = [NSString stringWithFormat:#"number_%d.png", remainder];
self.hundredImageView.image = [UIImage imageNamed:hundredString];
self.tenImageView.image = [UIImage imageNamed:tenString];
self.remainderImageView.image = [UIImage imageNamed:remainderString];
}
I have 9 buttons whose images are set by the user dynamically. Each button's current image is saved the user documents folder. In viewDidLoad id like to re-set each image to it's UIButton.
I can do this easily enough with:
NSString *filePath = [self documentsPathForFileName: #"boss1.png"];
NSData *pngData = [NSData dataWithContentsOfFile:filePath];
UIImage *savedBoss = [UIImage imageWithData:pngData];
[boss1Button setImage:savedBoss forState:UIControlStateNormal];
...... 8 more times....
Of course Id prefer to do it using a loop. Only, Im not sure what that would look like in objective C. In jQuery I could do something like:
$('.bosses').each(function( index ) {
var imageUrl='../images/boss'+(index+1)
$('#'+this.id).css('background-image', 'url(' + imageUrl + ')')
});
How can I create a similar objective-C loop that would increment the boss image name and button name similarly?
Furthermore, is there a better way to do this entirely?
I feel like maybe having an NSArray of image urls and an NSArray of UIButton names and pairing them together using a loop might be better.... but again I'm not sure what the syntax would look like for that here.
Try like this and have button tag like 1 to 8
for (id subview in self.view.subviews) {
if([subview isKindOfClass:[UIButton class]]) {
UIButton* button = (UIButton*)subview;
NSString *filePath = [self documentsPathForFileName:[NSString stringWithFromate#"boss%d.png", button.tag]];
NSData *pngData = [NSData dataWithContentsOfFile:filePath];
UIImage *savedBoss = [UIImage imageWithData:pngData];
[button setImage:savedBoss forState:UIControlStateNormal];
}
}
This will do.
it will be like:
//Add all the buttons in an array for easy loop
NSArray *array = #[btn1,btn2,btn3,btn4... etc];
NSString *name = #"BOSS";
int x = 1;
for(UIButton *btn in array){ // loop through all the buttons
NSString *filePath = [self documentsPathForFileName:[NSString stringWithFormat:#"%#%d.png",name,x]];
NSData *pngData = [NSData dataWithContentsOfFile:filePath];
UIImage *savedBoss = [UIImage imageWithData:pngData];
[btn setImage:savedBoss forState:UIControlStateNormal];
x++;
}
How do I write NSArray values to utilize a variable similar to this NSString:
Levelname=[NSString stringWithFormat:#"Background1Level%d.png",LevelNO];
[backgroundimagview setImage:[UIImage imageNamed:Levelname]];
Here is the code block I need to convert to use the LevelNO variable:
[character setImage:[UIImage imageNamed:#"character1_09.png"]];
character.animationImages=[NSArray arrayWithObjects:
[UIImage imageNamed:#"character1_01.png"],
[UIImage imageNamed:#"character1_02.png"],
[UIImage imageNamed:#"character1_03.png"],
[UIImage imageNamed:#"character1_04.png"],nil ];
loop through them with an integer and instead of "LevelNO" use that integer. Something like this:
for(int i = 0; i < {number of levels here}, i++)
{
Levelname=[NSString stringWithFormat:#"Background1Level%d.png",i];
[myArray addObject:[UIImage imageWithName:Levelname];
}
Make sure to keep an array and replace myArray