Inserting an NSString into NSBundle's pathForResource? - iphone

This animates the UIImageView in the impactdrawarray:
if ( ((impact *) [impactarray objectAtIndex:iv]).animframe == 70){
((UIImageView *) [impactdrawarray objectAtIndex:iv]).image =
[UIImage imageWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:#"explosionA71"
ofType:#"png"]];
}
if ( ((impact *) [impactarray objectAtIndex:iv]).animframe == 71){
((UIImageView *) [impactdrawarray objectAtIndex:iv]).image =
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:#"explosionA72"
ofType:#"png"]];
}
Nothing appears with this:
NSString *myString2 =
[NSString stringWithFormat:#"A%d",
((impact *) [impactarray objectAtIndex:iv]).animframe;
((UIImageView *) [impactdrawarray objectAtIndex:iv]).image =
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:(#"explosion%d", myString2)
ofType:#"png"]];
My reference for using NSString (example)
NSString *myString23 = [NSString stringWithFormat:#"$%d", money];
moneylabel.text = myString23;
How can I use a variable in the file name? Is there a way to load an image in a resource folder by index? something like imageByIndex:currentanimationframe? I didn't see anything in the UIImage documentation.
Response to comments:
NSString *myString2 = [NSString stringWithFormat:#"A%d", ((impact *) [impactarray objectAtIndex:iv]).animframe];
((UIImageView *) [impactdrawarray objectAtIndex:iv]).image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"explosion%d", myString2] ofType:#"png"]];
and
NSString *imagename = [NSString stringWithFormat:#"A%d", ((impact *) [impactarray objectAtIndex:iv]).animframe];
UIImage *myImage = [UIImage imageNamed:imagename];
((UIImageView *) [impactdrawarray objectAtIndex:iv]).image = myImage;
Both compile and run, but the image does not show.

Use +stringWithFormat:, just as in your example:
[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"explosion%d", myString2] ofType:#"png"];

NSString* imageName = [self dynamicallyCalculateImageNameUsingCrazyMath];
UIImage* myImage = [UIImage imageNamed:imageName];

Related

Can't tweet an image

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
forTweet = TRUE;
switch(buttonIndex)
{
case 0:
{
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
// Set the initial tweet text. See the framework for additional properties that can be set.
NSMutableString * twitterString = [displayString mutableCopy];
[twitterString appendString: #" #LoviOtvet"];
[tweetViewController setInitialText: twitterString];
UIImage * imageAnswer = [self getImageFromURL: [self strToUrlConverter]];
UIImage * imageLogo = [[UIImage alloc] initWithContentsOfFile: #"image.png"];
[tweetViewController addImage: [self mergeImage:imageAnswer withImage:imageLogo strength:1]];
break;
}
I added . No errors, but not working.
Facebook and saving to device working. Tweeting not. Why not?
Your problem is this line:
UIImage * imageLogo = [[UIImage alloc] initWithContentsOfFile: #"image.png"];
For this method, you would need to need to provide a file path, not a name. You have two choices:
UIImage * imageLogo = [UIImage imageNamed:]
or (for a file in the bundle):
NSString *path = [[NSBundle mainBundle] pathForResource:#"image" ofType:#"png"];
UIImage * imageLogo = [[UIImage alloc] initWithContentsOfFile:path];

Download Image and UIButton BG image

I am trying to do download some images from server then , set these images as background image for some UIButtons .
so first downloading images :
NSString *urlMag1 = [NSString stringWithFormat:#"http://myweb.com/i224_mag1.png"];
NSString *urlMag2 = [NSString stringWithFormat:#"http://myweb.com/i224_mag2.png"];
NSString *str = [NSString stringWithFormat:urlMag1,urlMag2,nil];
NSData *data = [NSData dataWithContentsOfFile:str];
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[data writeToFile:path atomically:YES];
UIImage *imgMag1 = [UIImage imageNamed:#"i224_mag2.png"];
[mag2 setBackgroundImage:imgMag1 forState:UIControlStateNormal];
but nothing happens !!,and how can I check to if these images are in directory to avoid more downloading
I would be grateful if you help me to solve this
thanks !
EDITED
#Fernando Cervantes
I created a method to set buttons BG images something like this , but I don't know why does not work !
- (UIImage *)loadImages :(NSString *)fileNames ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
[[NSFileManager defaultManager] fileExistsAtPath:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", fileNames, extension]]];
return 0;
}
and set BG images :
- (void)buttonsBGImage {
UIImage * bgMag2 = [self loadImages:#"i224_mag2" ofType:#"png" inDirectory:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
[mag2 setBackgroundImage:bgMag2 forState:UIControlStateNormal];
}
but actually nothing happens ! even I check the file and it's in app directory
The following approach might help you out a bit.
Save
-(void) saveFile:(NSString *)fileName ofType:(NSString *)extension fromURL:(NSString *)fileIndexPath inDirectory:(NSString *)directoryPath {
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileIndexPath]];
[data writeToFile:[NSString stringWithFormat:#"%#/%#.%#", directoryPath, fileName, extension] atomically:YES];
}
Check
-(BOOL) checkIfFileExists:(NSString *)fileName ofType:(NSString *)extension inDirectoryPath:(NSString *)directoryPath {
bool result;
if ([[NSFileManager defaultManager] fileExistsAtPath:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", fileName, extension]]]) {
result = TRUE;
} else {
result = FALSE;
}
return result;
}
Set
UIButton * button = [[UIButton alloc] init];
UIImage * backgroundImage = [self loadImage:#"YourImageName" ofType:#"png" inDirectory:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
[button setImage:backgroundImage forState:UIControlStateNormal];
-Edited-
I believe your problem is that you are returning 0 in your loadImages method. Instead of returning the image itself.
This is how I accomplished it:
Load
-(UIImage *) loadImage:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/%#.%#", directoryPath, fileName, extension]];
return result;
}
[UIImage imageNamed:#"i224_mag2.png"]; // it is only for bundle. You should use
[UIImage imageWithContentsOfFile:path]
or
[UIImage imageWithData:data];
Update:
I use category for UIButton class.
- (void)loadImage:(NSString *)URL withActivityIndicator:(BOOL)hasActivity refreshObject:(UIView *)refresh{
// load image from cache cutted
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
NSData *image = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:URL]];
//this will set the image when loading is finished
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *loadedImage = [UIImage imageWithData:image];
// add image to cache cutted
[self setImage:loadedImage forState:UIControlStateNormal];
});
});
}
You are making NSData using dataWithContentsOfFile: API. you should use dataWithContentsOfURL instead.
NSString *urlMag1 = [NSString stringWithFormat:#"http://myweb.com/i224_mag1.png"];
NSString *urlMag2 = [NSString stringWithFormat:#"http://myweb.com/i224_mag2.png"];
NSData *image1 = [NSdata contentsOfURL:[NSURL URLWithString:urlMag1]];
NSData *image2 = [NSdata contentsOfURL:[NSURL URLWithString:urlMag2]];
[mag2 setBackgroundImage:imgMag1 forState:UIControlStateNormal];
Usually [NSdata contentsOfURL:[NSURL URLWithString:urlMag1]]; will freeze UI until image downloading complete.

UISlider controlling UIImageView

I'm trying to make a UISlider control the picture shown in a UIImageView. Slider min is 0, max is 50.
The problem is the UIImageView only react to the else and chosenTime = 50.
Only then corresponding picture are shown in the UIImageView.
48 and 49 are ignored, the "else" picture is shown in these cases.
Any help is much appreciated!
Here's the code:
-(IBAction) sliderChanged:(id)sender{
UISlider *slider = (UISlider *) sender;
int prog = (int)(slider.value + 0.5f);
NSString * newText = [[NSString alloc] initWithFormat:#"%d", prog];
sliderLabel.text = newText;
int chosenTime = [newText intValue];
NSLog(#"chosenTime is %i", chosenTime);
//chosenTime is confirmed int value in the NSLOG!!!
if (chosenTime == 1) {
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:#"/Pic0001.png"];
clockView.image = [UIImage imageWithContentsOfFile:fullpath];
}
if (chosenTime == 48) {
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:#"/Pic0048.png"];
clockView.image = [UIImage imageWithContentsOfFile:fullpath];
}
if (chosenTime == 49) {
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:#"/Pic0049.png"];
clockView.image = [UIImage imageWithContentsOfFile:fullpath];
}
if (chosenTime == 50) {
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:#"/Pic0050.png"];
clockView.image = [UIImage imageWithContentsOfFile:fullpath];
} else {
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:#"/Pic0000.png"];
clockView.image = [UIImage imageWithContentsOfFile:fullpath];
}
}
I simplified the code a little bit. Make sure the NSLogged numbers are in the range 1-50. If not, the slider's minimum/maximum values are misconfigured.
-(IBAction) sliderChanged: (UISlider *) sender
{
int chosenTime = (int) ceilf(slider.value);
NSLog(#"chosenTime is %i", chosenTime);
//chosenTime is confirmed int value in the NSLOG!!!
if (chosenTime > 50)
chosenTime = 0;
NSString *fileName = [NSString stringWithFormat: #"Pic00%02d.png", chosenTime];
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: fileName];
clockView.image = [UIImage imageWithContentsOfFile: fullpath];
}
The problem with your code is the absence of else after each if. The comparisons fall through to the last if, after which it's either 50 or not 50, and not being 50 is treated as zero.

UIImageView doesn't animate

I have the following code inside my app, but it doesn't animate the UIImageView, can anyone tell me why?
UITableViewCell* cell = [selectedTable cellForRowAtIndexPath:selectedPath];
NSArray* myImageArray = [NSArray arrayWithObjects:
[UIImage imageNamed:[[NSBundle mainBundle] pathForResource:#"boxBeingChecked117x11" ofType:#"png"]],
[UIImage imageNamed:[[NSBundle mainBundle] pathForResource:#"boxBeingChecked217x11" ofType:#"png"]],
[UIImage imageNamed:[[NSBundle mainBundle] pathForResource:#"boxBeingChecked317x11" ofType:#"png"]],
[UIImage imageNamed:[[NSBundle mainBundle] pathForResource:#"boxBeingChecked417x11" ofType:#"png"]],
[UIImage imageNamed:[[NSBundle mainBundle] pathForResource:#"boxBeingChecked517x11" ofType:#"png"]],
[UIImage imageNamed:[[NSBundle mainBundle] pathForResource:#"boxBeingChecked617x11" ofType:#"png"]],
nil];
cell.imageView.animationImages = myImageArray;
cell.imageView.animationDuration = 4.20;
cell.imageView.animationRepeatCount = 1;
[cell.imageView startAnimating];
[NSTimer scheduledTimerWithTimeInterval:4.0
target:self
selector:#selector(methodToInvokeAfterAnimationIsDone)
userInfo:nil
repeats:NO];
You should use this:
NSArray* myImageArray = [NSArray arrayWithObjects:
[UIImage imageNamed:#"boxBeingChecked117x11.png"]],
[UIImage imageNamed:#"boxBeingChecked217x11.png"]],
[UIImage imageNamed:#"boxBeingChecked317x11.png"]],
[UIImage imageNamed:#"boxBeingChecked417x11.png"]],
[UIImage imageNamed:#"boxBeingChecked517x11.png"]],
[UIImage imageNamed:#"boxBeingChecked617x11.png"]],
nil];
You need to give name of the file, not the path, in imageNamed: method.
Make sure that the imageView's highlighted property is set to NO, otherwise the code you have above will not work. If you want to animate highlighted images, use highlightedAnimationImages.

When to release UIImage and NSString Resources

I'm trying to get my memory management right and in the code below, if I include the final release statement (the one for filePath), it crashes and I can't see why. I've alloc'ed it, so why shouldn't I release it?
Further down, I return cellAbout to the TableView.
Can someone explain?
UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
filePath = [filePath stringByAppendingString:#".png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
imageView.image = image;
[image release];
[filePath release];
Many thanks,
Chris.
The answer is that the original filePath string IS alloced and needs to be released, but when you have the line:
filePath = [filePath stringByAppendingString:#".png"];
you create a different string - the original pointer to filePath is now gone and is a leak.
Here is the code you actually want
NSString *filePath = self.gem.poiType;
filePath = [filePath stringByAppendingPathExtension:#"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
imageView.image = image;
[image release];
So you don't need to release the filePath - it is auto released. Also apple has a special call for adding path extensions.
NSString *filePath = [self.gem.poiType stringByAppendingPathExtension:#"png"];
is actually how most people would write that code - one fewer lines.
Your Issues
UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
Leaking filePath after this line.
filePath = [filePath stringByAppendingString:#".png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
imageView.image = image;
[image release];
Releasing an autoreleased object after this line.
[filePath release];
Instead
UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
NSString *extendedFilePath = [filePath stringByAppendingString:#".png"];
[filePath release];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: extendedFilePath];
imageView.image = image;
[image release];
[NSString stringByAppendingString] returns a NEW string, so that's where you're leaking your old one.
And then filePath is no longer owned by you, so when you release it later, you crash.
You could sidestep this whole thing like this:
NSString *filePath = [NSString stringWithFormat:#"%#.png",self.gem.poiType];// don't release me.
You are leaking here and later releasing an autoreleased string:
filePath = [filePath stringByAppendingString:#".png"];
If you really want to manually release, save the pointer:
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
NSString *somestring = [filePath stringByAppendingString:#".png"];
[filePath release];