iOS: Add multiple UIImageViews programmatically in runtime - objective-c

So, I'm doing a Breakout-clone on the iPhone. All elements except the bricks to hit, are created and working as expected with the NIB-file.
However, if I want to create different levels and run collision detection on the bricks, it seems stupid to add them in Interface Builder. How do I add them to the view in code?
I got an image called "brick.png" that I want to use with an UIImageView. Also, I want to have arrays and / or lists with these so I can build cool levels with pattern in the bricks and all :)
How do I do this in code?

#Mark is right, I would just add where the image need to be displayed!
UIImageView *imgView = [[[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 100, 20)] autorelease];
NSString *imgFilepath = [[NSBundle mainBundle] pathForResource:#"brick" ofType:#"png"];
UIImage *img = [[UIImage alloc] initWithContentsOfFile:imgFilepath];
[imgView setImage:img];
[img release];
[self.view addSubview:imgView];
I tested the code and for me only shows when told the coordinates

It's really pretty easy. Here's an example of how you would create and display a UIImageView programatically...
UIImageView *imgView = [[[UIImageView alloc] init] autorelease];
NSString *imgFilepath = [[NSBundle mainBundle] pathForResource:#"brick" ofType:#"png"];
UIImage *img = [[UIImage alloc] initWithContentsOfFile:imgFilePath];
[imgView setImage:img];
[img release];
[self.view addSubview:imgView];
That's pretty much all there is to it.

Related

Unable to load an image into NSImageView

I wrote the following and no image comes up. I displayed the pointer and it comes out as "0".
In the next code block I checked the path and made shore the image was present there. Still nothing loads.
NSImageView *vi = [[NSImageView alloc] initWithFrame:CGRectMake(10, 10, 220, 220)];
[self.view addSubview:vi];
NSImage *dog = [NSImage imageNamed:#"airnow3.jpg"];
NSLog(#"pointer %d", dog);
[vi setImage:dog];
NSFileManager *filemgr;
NSString *currentpath;
filemgr = [[NSFileManager alloc] init];
currentpath = [filemgr currentDirectoryPath];
NSLog(#"%#", currentpath);
Why don't you use InitWithImage:(NSImage) instead of InitWithFrame
Maybe you should use UIImageView.
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(10,10,220,220)];
UIImage *image = [UIImage imageNamed:#"airnow3.jpg"];
[imageView setImage: image];
[self.view addSubview: imageView];

ImageView Animation getting more Memory

My application is in ARC.
I am using image Animation in imageView but after some period of time my application crashed with low memory error.
I am not getting any error message in Log but in Profile tool i am getting "Low Memory" message in allocation Part.
One code of my Animation is
ImageView= [[UIImageView alloc] init];
[self.view addSubview:ImageView];
ImageView.frame=CGRectMake(0, 0, 480, 342);
ImageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image1" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image2" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image3" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image4" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image5" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image6" ofType:#"png"]],
nil];
[ImageView setAnimationRepeatCount:1];
ImageView.animationDuration =1.0;
[ImageView startAnimating];
If i comment this animation code then application is running correctly but i need more than 5 this type of animation in one view.
Any Link, tutorial, any Idea will be great help...
Why don't you try with a sprite? I've tried to animate with CALater (Core Animation Layer) and it works like a charm. I animate the 'contentsRect'. Short code example (CALayer subclass):
self.contents = [UIImage imageNamed:#"sprite-large.png"].CGImage;
NSMutableArray *frames = [NSMutableArray array]; // array of CGRect's
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"contentsRect"];
anim.values = frames;
[self addAnimation:anim forKey:nil];
I've posted some code to GitHub a few weeks ago:
https://github.com/Gerharbo/sprite-animation-layer/
It provides an example sprite (not perfect, but it works) and some example code.
Have fun animating!
Gerhard
Gerharbo's method is basically a texture atlas but with one much bigger image. What I think you will find is that this kind of approach does not scale well when you try to use many images (for a long animation). You are already seeing crashes caused by running out of memory, so it would be a good idea to completely avoid UIImageView.animationImages. This blog post video-and-memory-usage-on-ios-devices describes why you cannot allocate memory to hold a bunch of images in main memory, which is exactly what you code above is trying to do. If you look around on SO you will find many other developers have ran into this same issue.

Show an image from json

I'm not able to show an image that I load from a json file.
I'm parsing my json with JSONKit and everything works fine but I can't load an image in the UIImageview. I hope some of you can help me out there.
below my code I thought might be correct but it isn't.
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 100, 115)];
image.image = [UIImage imageNamed:[detailView objectForKey:#"thumbnail"]];
[self.view addSubview:image];
[image release];
i think in json u are getting url of image. display image from url using below code
//NSURL *url = [NSURL URLWithString:#"http://192.168.1.2x0/pic/LC.jpg"];
NSURL *url = [NSURL URLWithString:[detailView objectForKey:#"thumbnail"]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImageView *subview = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,320.0f, 460.0f)];
[subview setImage:[UIImage imageWithData:data]];
[self.view addSubview:subview];
[subview release];
the code you posted
image.image = [UIImage imageNamed:[detailView objectForKey:#"thumbnail"]];
will try to find the image on your bundle named the string stored in [detailView objectForKey:#"thumbnail"]
As you mentioned, your images are from remote server, you have to download the image from your remote server.
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 100, 115)];
image.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[detailView objectForKey:#"thumbnail"]]]];
[self.view addSubview:image];
[image release]

Trying to load images in my slot machine iPhone app but getting an error (NSInvalidArgumentException)

I'm new to the hole Xcode/objective-c thing so it would be kind answering my questions in a way I can understand you :)
My problem is: I'm trying to create a slot machine with a picker and a button (to spin the wheels of course ;) ) so I'm implementing 5 images (apple,crown,cherry,lemon,seven,banana) but at the point when I start the app I get this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImage initWithImage:]: unrecognized selector sent to instance 0x4b649b0'
My code looks like this:
- (void)viewDidLoad {
UIImage *apple = [UIImage imageNamed:#"apple.png"];
UIImage *banana = [UIImage imageNamed:#"banana.png"];
UIImage *cherry = [UIImage imageNamed:#"cherry.png"];
UIImage *crown = [UIImage imageNamed:#"crown.png"];
UIImage *lemon = [UIImage imageNamed:#"lemon.png"];
UIImage *seven = [UIImage imageNamed:#"seven.png"];
for (int i = 1; i <= 5; i++) {
UIImageView *appleView = [[UIImage alloc] initWithImage:apple];
UIImageView *bananaView = [[UIImage alloc] initWithImage:banana];
UIImageView *cherryView = [[UIImage alloc] initWithImage:cherry];
UIImageView *crownView = [[UIImage alloc] initWithImage:crown];
UIImageView *lemonView = [[UIImage alloc] initWithImage:lemon];
UIImageView *sevenView = [[UIImage alloc] initWithImage:seven];
NSArray *imageViewArray = [[NSArray alloc] initWithObjects:appleView, bananaView, cherryView, crownView, lemonView, sevenView, nil];
NSString *fieldName = [[NSString alloc] initWithFormat:#"column%d", i];
[self setValue: imageViewArray forKey:fieldName];
[fieldName release];
[imageViewArray release];
[appleView release];
[bananaView release];
[cherryView release];
[crownView release];
[lemonView release];
[sevenView release];
I've been looking around for typos quite some time but didn't find any. It would be really nice if someone could give me a hint. If the supported code isn't enough, feel free to ask for more.(Just copied the section where the error occurred) Sorry for my bad english but it's not my native language :)
/edit: I should've said, that the original error had been: SIGABRT, but it looks like this error seems to mean a lot without any context :)
You need to create your image views with
[[UIImageView alloc] initWithImage: ...]
NOT
[[UIImage alloc] initWithImage: ...]

Creating a method for wrapping a loaded image in a UIImageView

I have the following un my applicationDidFinishLaunching method
UIImage *image2 = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image2.jpg" ofType:nil]];
view2 = [[UIImageView alloc] initWithImage:image2];
view2.hidden = YES;
[containerView addSubview:view2];
I'm simply adding an image to a view. But because I need to add 30-40 images I need to wrap the above in a function (which returns a UIImageView) and then call it from a loop.
This is my first attempt at creating the function
-(UIImageView)wrapImage:(NSString *)imagePath
{
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:imagePath
ofType:nil]];
UIImageView *view = [[UIImageView alloc] initWithImage:image];
view.hidden = YES;
return view;
}
And then to invoke it I have the following so far, for simplicity I am only wrapping 3 images
//Create an array and add elements to it
NSMutableArray *anArray = [[NSMutableArray alloc] init];
[anArray addObject:#"image1.jpg"];
[anArray addObject:#"image2.jpg"];
[anArray addObject:#"image3.jpg"];
//Use a for each loop to iterate through the array
for (NSString *s in anArray) {
UIImageView *wrappedImgInView=[self wrapImage:s];
[containerView addSubview:wrappedImgInView];
NSLog(s);
}
//Release the array
[anArray release];
I have 2 general questions
Is my approach correct?, ie following best practices, for what I am trying to do (load a multiple number of images(jpgs, pngs, etc.) and adding them to a container view)
For this to work properly with a large number of images, do I need to keep my array creation separate from my method invocation?
Any other suggestions welcome!
Just a note, in function declaration you should return pointer to UIImageView, not an UIImageView itself (i.e. add an asterisk).
Also, when returning the view from the function you should autorelease it. Otherwise it will leak memory. So initialization should look something like this:
UIImageView *view = [[[UIImageView alloc] initWithImage:image] autorelease];
Everything else seems to look good.