How to replace a number as an image in Xcode 5 - ios

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];
}

Related

Sending a tag value to NSMutableArray objectAtIndex returns null

I have a list of product details as objects in NSMutableArray and list of product images as a gallery, I need to load full image on click of thumbnail images. For that, I set tag and get a exact tag value on click of particular image. The problem is I can't get the array objects.I test with manual numbers, array returns objects perfectly. What i did wrong here?
Tag setting code:
for(int index=0; index < [self.sliderImages count]; index++)
{
UIImageView *imageView = [[UIImageView alloc]init];
imageView.frame = CGRectMake(xOffset, 0, 100, scrollHeight);
imageView.tag = index;
Products *product = [self.sliderImages objectAtIndex:index];
NSLog(#"product name %#",product.name);
NSString *imageUrl = [NSString stringWithFormat:#"%#",product.imagePath];
}
Tap gesture recognizer method:
- (void) tapGesture:(id)sender
{
//handle Tap...
UIImageView *tmp = (UIImageView *)[sender view];
int tm = (int)(tmp.tag);
NSLog(#"self.sliderImages%#",[self.sliderImages objectAtIndex:tm]);
Products *product = [self.sliderImages objectAtIndex:tm];
NSLog(#"product%#",product);
NSLog(#"product ges %#,, %#",product.name,product.imagePath);
NSString *imageUrl = [NSString stringWithFormat:#"%#",product.imagePath];
NSLog(#"full image path :: %#",imageUrl);
[self loadFullImage:tm];
}
Are you sure you are not getting nil in the tag? (int tm = (int)(tmp.tag))
How are you getting the clicks on the UIImageView? Are you using gesture recognizer?
If you are using gesture recognizer then try like this to receive the touch and tags for the same
(void)touch:(UIGestureRecognizer *)recognizer

Receiveing array of Images from CoreData

I've created NSManagedObject* imagesArrayData that stores strings (paths) to images stored in the documents directory:
- (void)setImagesArray:(NSMutableArray *)imagesArray {
NSMutableArray* newImagesArray = [NSMutableArray new];
int i = 1;
for (UIImage* image in imagesArray) {
//generate path to createdFile
NSString* fileName = [NSString stringWithFormat:#"%#_%d", self.name, i];
NSString* filePath = [self documentsPathForFileName:fileName];
//save image to disk
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:filePath atomically:YES];
//add image path to CoreData
[newImagesArray addObject:filePath];
i++;
}
//set new value of imagesArray
imagesArrayData = [NSKeyedArchiver archivedDataWithRootObject:newImagesArray];
I am now not showing pathsToImages in header file, but property imagesArray:
-(NSMutableArray*) imagesArray {
NSMutableArray* images = [NSMutableArray new];
NSArray* imagePaths = [NSKeyedUnarchiver unarchiveObjectWithData:imagesArrayData];
for (NSString* imagePath in imagePaths) {
UIImage *image = [[UIImage alloc] initWithContentsOfFile: imagePath];
[images addObject:image];
}
return images;
The problem is, that whenever I want to get to [imagesArray objectatIndex:xxx], the imagesArray getter is called, and it takes time to recreate the full array. When trying to switch fast between images, the UI slows down.
What would be the elegant way to overcome this problem? Maybe creating another array full of images and updating it from time to time? Maybe something else? Please, help.
One thing you could do is refactor your getter to lazily load the array. If it is already defined, simply return it. If not, build it:
-(NSMutableArray*) imagesArray
{
if (!_imagesArray)
{
NSMutableArray* _imagesArray = [NSMutableArray new];
NSArray* imagePaths =
[NSKeyedUnarchiver unarchiveObjectWithData: imagesArrayData];
for (NSString* imagePath in imagePaths)
{
UIImage *image = [[UIImage alloc] initWithContentsOfFile: imagePath];
[_imagesArray addObject:image];
}
return _imagesArray;
}
I'm not sure what you mean about updating an array of images from time to time.
If your array of image names changes you will need some method to respond to those changes.

Adding UIImage to NSMutable array for an animation

I have an app that creates an animation from images stored in a group in my project navigator (not Images.xcassets). This code "works" in that it animates properly, but using imageNamed causes a memory leak because the image files are not getting deallocated.
I can't figure out why adding with imageNamed: works adds images to my array, but imageWithContentsOfFile: doesn't.
A little info on the mechanics of my app:
self.myPhoto is set on the segue from another ViewController. The number of images can vary, so I test to see the file is "there" before adding it to the array.
Filenames follow this naming convention:
"1-1.jpg"
"2-1.jpg"
"2-2.jpg"
"99-1.jpg"
"99-2.jpg"
"99-3.jpg"
"99-4.jpg"
This code works, but the images don't deallocate, causing a memory leak:
- (void)startAnimation {
NSMutableArray *imageArray = [[NSMutableArray alloc] init];
for (int imageNumber = 1; self.myPhoto != nil; imageNumber++) {
NSString *fileName = [NSString stringWithFormat:#"%#-%d.jpg", self.myPhoto, imageNumber];
// check if a file exists
if ([UIImage imageNamed:fileName]) {
// if it exists, add it to the array
[imageArray addObject:[UIImage imageNamed:fileName]];
} else {
// otherwise, don't add image to the array
break;
}
}
self.myImageView.animationImages = imageArray;
self.myImageView.animationDuration = 1.5f;
self.myImageView.animationRepeatCount = 0;
self.myImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.myImageView startAnimating];
}
I ran Instruments on it and saw I had a memory leak emanating from my animation. Digging around a little on StackOverflow, I discovered the manner I'm adding my files to myArray results in images not getting deallocated.
So I tried this, instead:
- (void)startAnimation {
NSMutableArray *imageArray = [[NSMutableArray alloc] init];
for (int imageNumber = 1; self.myPhoto != nil; imageNumber++) {
NSString *fileName = [NSString stringWithFormat:#"%#-%d", self.myPhoto, imageNumber];
// check if a file exists
if ([UIImage imageNamed:fileName]) {
// if it exists, add it to the array
[imageArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:#"%#", fileName] ofType:#"jpg"]]];
NSLog(#"%# added to imageArray", fileName);
} else {
// otherwise, don't add image to the array
break;
}
}
NSLog(#"There are %lu images in imageArray", (unsigned long)imageArray.count);
self.myImageView.animationImages = imageArray;
self.myImageView.animationDuration = 1.5f;
self.myImageView.animationRepeatCount = 0;
self.myImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.myImageView startAnimating];
}
When I do it this way, the page where the animation loads appears, but the images don't get added to my array--the . This is a well-documented issue. Here are a few posts covering this problem:
Dirty Memory because of CoreAnimation and CG image
How do I use imageWithContentsOfFile for an array of images used in an animation?
Thank you for reading. I'm stumped, though I'm confident the resolution to this problem is a startlingly stupid oversight on my part. Prove me right ;)
I made some minor changes out of desperation and I stumbled into the "answer". Comments note where I made changes:
- (void)startAnimation {
NSMutableArray *imageArray = [[NSMutableArray alloc] init];
for (int imageNumber = 1; self.myPhoto != nil; imageNumber++) {
// I set the filename here, adding .jpg to it
NSString *fileName = [NSString stringWithFormat:#"%#-%d.jpg", self.myPhoto, imageNumber];
// check if a file exists
if ([UIImage imageNamed:fileName]) {
// if it exists, add it to the array
// I blanked out ofType, as it's set when I create the local fileName variable
[imageArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:#"%#", fileName] ofType:#""]]];
} else {
// otherwise, don't add image to the array
break;
}
}
self.myImageView.animationImages = imageArray;
self.myImageView.animationDuration = 1.5f;
self.myImageView.animationRepeatCount = 0;
self.myImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.myImageView startAnimating];
}

Using an NSMutableArray to set images to multiple UIImageViews

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.

array size different in simulator then on iphone

I have the following code:
NSMutableArray *imageArray = [[NSMutableArray alloc] init];
for(int i = 1; i <= 32; i++) {
//NSString *str = [NSString stringWithFormat:#"marker_%i.png", i];
NSString *str = [NSString stringWithFormat:#"wave%i.png", i];
UIImage *img = [UIImage imageNamed:str];
if(img != nil) {
[imageArray addObject:img];
}
}
NSLog(#"imageArray count %i",[imageArray count]);
NSMutableArray *reverseArray = [NSMutableArray arrayWithArray:imageArray];
[[reverseArray reverseObjectEnumerator] allObjects];
[imageArray addObjectsFromArray:reverseArray];
NSLog(#"imageArray count %i",[imageArray count]);
If i run it on the iphone i get:
2013-05-12 15:21:08.539 RouteApp[5673:907] imageArray count 23
2013-05-12 15:21:08.545 RouteApp[5673:907] imageArray count 46
while if i run in the simulator i get 32 and 64 like i expect.
(like if the numbers are switched)
What can cause this?
It looks like some of the images are missing on the iPhone, so this line
if(img != nil) {
[imageArray addObject:img];
}
filters them out. Change this line as follows to see which images are not present:
if(img != nil) {
[imageArray addObject:img];
} else {
NSLog("Image 'wave%i.png' is missing", i);
}
Filenames on the device are case-sensitive, but are not on the simulator. Some of your image names are likely slightly different from the format you're expecting.
The most common way this happens is something like wave01.png vs. wave01.PNG.
Otherwise it's probably something like wave01.png vs. Wave01.png, etc.

Resources