I've started from the standard PageView-based application template provided by Apple. Now instead of text I want the pages in the app to display images. An array is created as follows:
_pageData = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
nil];
This array is handled the following way:
DataViewController *dataViewController = [storyboard instantiateViewControllerWithIdentifier:#"DataViewController"];
dataViewController.dataObject = [self.pageData objectAtIndex:index];
return dataViewController;
Then, in DataViewController.h:
#interface DataViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (strong, nonatomic) UIImage *dataObject;
And in DataViewController.m I'm trying to display the images in de imageView in the following way:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.imageView = [[UIImageView alloc] initWithImage:_dataObject];
NSLog(#"dataObject %#", _dataObject);
}
However, with this code I'm not succeeding in getting the images onto the PageViewController. Any idea how I could get this working properly?
A big thanks for you help!
Here
self.imageView = [[UIImageView alloc] initWithImage:_dataObject];
you are creating a new UIImageView that is dangling arround unused, invisible and without a parent.
You need to set it's size somehow and put it to a parent view with a
[<parent> addSubview:self.imageView]
to show it.
If your original UIImageView is read from a resource file ( I assume so because it is a IBOutlet ),
just do a
self.imageView.image = _dataObject
and this should do the job instead.
This worked for me
NSArray *anArray = [NSArray arrayWithObjects:
[UIImage imageNamed:#"transparente.png"],
[UIImage imageNamed:#"21001.jpg"],
[UIImage imageNamed:#"21002.jpg"],
[UIImage imageNamed:#"21003.jpg"],
[UIImage imageNamed:#"21004.jpg"],
[UIImage imageNamed:#"transparente2.png"],
nil];
_pageData = [anArray copy];
and in the dataViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.pageImage.image = self.dataObject;
}
The pageImage is an UIImageView with an IBOutlet.
Related
I am building a simple application to show images.
I send the image url, and it should be downloading.
This is my code:
#import "ImageViewController.h"
#interface ImageViewController ()
#property (nonatomic, strong) UIImageView * imageView;
#property (nonatomic, strong) UIImage * image;
#end
#implementation ImageViewController
-(void)setImageURL:(NSURL *)imageURL{
_imageURL = imageURL;
self.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]];
}
-(UIImageView*)imageView{
if(!_imageView)
return [[UIImageView alloc]init];
return _imageView;
}
-(UIImage*)image{
return self.imageView.image;
}
-(void)setImage:(UIImage *)image{
self.imageView.image = image;
[self.imageView sizeToFit];
}
-(void)viewDidLoad{
[self.view addSubview:self.imageView];
NSLog(#"Image Url = %#", self.imageURL);
}
#end
I call it like this:
if ([segue.destinationViewController isKindOfClass:[ImageViewController class]]){
ImageViewController* ivc = (ImageViewController*)segue.destinationViewController;
ivc.imageURL = [[NSURL alloc]initWithString:[NSString stringWithFormat:#"http://images.apple.com/v/iphone-5s/gallery/a/images/download/%#.jpg", segue.identifier]];
I am 100% sure that the passed url is correct because I already check that through debugging
The image is absolutely being downloaded because its size is large and the screen is blocking while downloading it.
The problem is the that imageView doesn't show it after finishing downloading.
Could u help me please?
Edit
The header file
#import <UIKit/UIKit.h>
#interface ImageViewController : UIViewController
#property(nonatomic, strong) NSURL* imageURL;
#end
This is all my code, so you can test it if you want.
Edit2
I have a scroll view, maybe that is the problem ?
Please check the image
You have an issue in the getter of the imageView property. You are not initialising the attribute, but returning a different object each time. Replace the line:
return [[UIImageView alloc]init];
by
_imageView = [[UIImageView alloc]init];
Please try to edit your code as following it is working for me, in your case problem may be because you are passing url from different view controller that you are :
[self.imageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://images.apple.com/v/iphone-5s/gallery/a/images/download/photo_1.jpg"]]]];
You can check from attached screen shot..
Set the imageView's frame instead of sending sizeToFit method.
-(void)setImage:(UIImage *)image{
self.imageView.image = image;
// [self.imageView sizeToFit];
self.imageView.frame = CGRectMake(100.0, 100.0, image.size.width, image.size.height) ;
}
Edit :
I see there is a scrollView on 'self.view', so it may block self.imageView, try to bring it to front using [self.view bringSubviewToFront:self.imageView] ; if you want it be the topmost of all subView on self.view.
You are not assigning you newly created imageView to your _imageView. So every time it triggers imageView method, it returns a new UIImageView. try this...
- (UIImageView*)imageView
{
if(!_imageView) {
_imageView = [[UIImageView alloc]init];
return _imageView;
}
return _imageView;
}
Just started Objective-C - trying to make 4 images fadein/fadeout continuously.
The code below is not working. I know the button is working because the text of my label changes, however no pictures animate. No errors either ...
h.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
IBOutlet UIImageView *viewer;
}
#property (nonatomic, retain) UIImageView *viewer;
#property (nonatomic,retain) IBOutlet UILabel *label1;
#end
m.
-(IBAction)startImageViewAnimation
{
label1.text = #"CHECK?";
NSArray *animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"backgrounds_app1-01.png"],
[UIImage imageNamed:#"backgrounds_app2-02.png"],
[UIImage imageNamed:#"backgrounds_app3-03.png"],
[UIImage imageNamed:#"backgrounds_app4-04.png"],
nil];
viewer = [[UIImageView alloc] initWithFrame:self.view.frame];
viewer.animationImages = animationImages ;
viewer.animationRepeatCount = 2;
viewer.animationDuration= 4.0;
[viewer startAnimating];
[NSTimer scheduledTimerWithTimeInterval:4.0 target:self
selector:#selector(animationDone:)
userInfo:nil repeats:NO];
}
-(void)animationDone:(NSTimer*)inTimer
{
[inTimer invalidate];
inTimer = nil;
NSLog(#"animationDone ");
}
After initialising the image view, you'll have to add it as a subview:
viewer = [[UIImageView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:viewer];
I have around 300 images to be loaded for animation the images are named loading001.png, loading002.png, loading003.png, loading004.png………loading300.png
I am doing it in the following way.
.h file
#import <UIKit/UIKit.h>
#interface CenterViewController : UIViewController {
UIImageView *imgView;
}
#end
.m file
#implementation CenterViewController
- (void)viewDidLoad {
[super viewDidLoad];
imgView = [[UIImageView alloc] init];
imgView.animationImages = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"loading001.png"],
[UIImage imageNamed:#"loading002.png"],
[UIImage imageNamed:#"loading003.png"],
[UIImage imageNamed:#"loading004.png"],
nil];
}
- (IBAction)startAnimation:(id)sender{
[imgView startAnimating];
}
#end
Is there a efficient way to load the images into a array.
I had tried it with for loop but was not able to figure it out.
You may try out the following code to load images into an array in a better way
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *imgListArray = [NSMutableArray array];
for (int i=1; i <= 300; i++) {
NSString *strImgeName = [NSString stringWithFormat:#"loading%03d.png", i];
UIImage *image = [UIImage imageNamed:strImgeName];
if (!image) {
NSLog(#"Could not load image named: %#", strImgeName);
}
else {
[imgListArray addObject:image];
}
}
imgView = [[UIImageView alloc] init];
[imgView setAnimationImages:imgListArray];
}
There is an easier way to do this. You can simply use:
[UIImage animatedImageNamed:#"loading" duration:1.0f]
Where 1.0f is the duration to animate all the images. For this to work though, your images must be named like this:
loading1.png
loading2.png
.
.
loading99.png
.
.
loading300.png
That is, without padding with 0.
The function animatedImageNamed is available from iOS 5.0 onwards.
Depending on the size of your images, a 300 image animation sequence may be quite the memory hog. Using a a movie might be a better solution.
Your code will crash when run on the device, it is just not possible to decompress that many images into memory on iOS. You will get memory warnings and then your app will be killed by the OS. See my answer to how-to-do-animations-using-images-efficiently-in-ios for a solution that will not crash on the device.
I have three images that I want to rotate in the background. Below is what I have so far. I want to have a class where I can hold all these UIImageViews and display them randomly in the background. I read about UIView and the frame method but I have no idea how to add them since it only takes in one frame.
Thus, I used NSArray to hold all the objects instead. The only problem now is when a new background appears, the old background doesn't disappear. Now do I remove the old background?
It would be great if someone can point me in the right direction.
Thanks!
#interface ViewController : UIViewController
#property (strong, nonatomic) NSArray *imageArray;
#property (strong, nonatomic) UIImageView *imageView;
- (IBAction)buttonPressed:(UIButton *)sender;
#end
// .m file
#implementation ViewController
#synthesize imageArray;
#synthesize imageView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
imageView = [[UIImageView alloc] init];
UIImage *image1 = [UIImage imageNamed:#"image1.png"];
UIImage *image2 = [UIImage imageNamed:#"image2.png"];
UIImage *image3 = [UIImage imageNamed:#"image3.png"];
imageArray = [[NSArray alloc] initWithObjects:image1, image2, image3, nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonPressed:(UIButton *)sender {
NSUInteger index = arc4random_uniform(self.imageArray.count);
[imageView setImage:[imageArray objectAtIndex:index]];
}
#end
This:
[self.view insertSubview:current atIndex:0];
Is adding another view to your view hierarchy, but you are not removing the one you previously placed. So you have an ever-growing stack of UIVews. You are also placing the new view at the bottom of the stack.
try
[[[self.view subviews] objectAtIndex:[[self.view subviews] count]-1] removeFromSuperview];
[self.view addSubview:current];
Or better - as #Kaan suggests - have a single UIImageView and simply change it's UIImage property.
To do this, your array will contain your UIImages not your UIImageviews.
Your UIView can be an UIImageview, or it can contain a UIImageview.
The UIImageview has an image property which you can set.
Your code would look something like this...
self.imageArray = [[NSArray alloc] initWithObjects:image1, image2, image3, nil];
NSUInteger index = arc4random_uniform(self.imageArray.count);
UIImage *current;
current = [self.imageArray objectAtIndex:index];
self.imageview.image = current;
In your approach, you have created 6 objects - 3 UIImages and 3 UIImageViews.
What you want can be accomplished using 4 objects instead of 6, using less memory, making your app run more quickly and answering your question at the same time (also, i'm assuming you have background images of all the same size, the size of the device's screen).
I would suggest creating first, only one UIImageView:
//backgroundImage is an IVAR
backgroundImage = [[UIImageView alloc] init];
followed by three UIImages and place them in an NSArray:
UIImage *image1 = [UIImage imageNamed:#"image1.png"];
UIImage *image2 = [UIImage imageNamed:#"image2.png"];
UIImage *image3 = [UIImage imageNamed:#"image3.png"];
//imagesArray is an IVAR
imagesArray = [[NSArray alloc]] initWithObjects: image1, image2, image3, nil];
Finally, to change the background, call the random function and update the UIImageView image property instead of popping a different view on top of the view stack:
NSUInteger index = arc4random() % [imagesArray count];
[backgroundImage setImage:[imagesArray objectAtIndex:index]];
I've got this code trying to run a simple set of images in a cycle. All I have in the app is one UIImageView declared in my View Controller's .h file:
#property (strong, nonatomic) IBOutlet UIImageView *imageDisplay;
And the following in my .m file's viewDidLoad method:
NSMutableArray *imageView = [[NSMutableArray alloc] init];
[imageView addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"EyeAnim1.png"]]];
[imageView addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"EyeAnim2.png"]]];
[imageView addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"EyeAnim3.png"]]];
[imageView addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"EyeAnim4.png"]]];
[imageView addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"EyeAnim5.png"]]];
[imageView addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"EyeAnim6.png"]]];
[imageView addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"EyeAnim7.png"]]];
imageDisplay.animationImages = imageView;
imageDisplay.animationDuration = 0.25;
imageDisplay.animationRepeatCount = 50;
[imageDisplay startAnimating];
The code seems to be crashing on the "imageDisplay.animationImages" line, as if I create the UIImageView, create its getter and setter, and build, it's fine until I uncomment that line. If I do uncomment it, it keeps giving me the error until I delete the UIImageView and create a new one.
Not too sure what's happening, any help appreciated!
I am very new to objective-c and I have been getting this error also, but for a different reason. I just wanted to post my solution for anyone else who may be struggling.
So basically I have a custom class called ImagesDetailViewController which inherits from UIViewController and has an image property.
#interface ImagesDetailViewController : UIViewController
#property (strong, nonatomic) UIImage *image;
#end
I then connected my class to my UIImageView on my storyboard like so
#interface ImagesDetailViewController ()
#property (nonatomic, weak) IBOutlet UIImageView *imageView;
#end
In my viewDidLoad method I was trying to set the image for my image view like this and getting the error mentioned above (my image variable gets initialised in a prepareForSegue method)
- (void)viewDidLoad
{
[super viewDidLoad];
[self.imageView setImage:self.image];
}
So I was stumped as I bet you are all too. The problem had to do with the storyboard. Clicking on my UIImageView and then navigating to the Connections Inspector, I had somehow created 2 referencing outlets (oops...) and one was pointing to a variable called image. So when the program was running [self.imageView setImage:self.image] self.image was actually an instance of UIImageView instead of UIImage.
animationImages array MUST contain only UIImage objects. Your array contains UIImageView objects.
Also your code is unsafe - if one of the resources will not exist app will crash (trying to add nil object to the mutable array). This will be much safer:
#define kNumberOfImages 7
NSMutableArray *imageView = [[NSMutableArray alloc] init];
for(NSUInteger i = 1; i <= kNumberOfImages; i++) {
UIImage *anImage = [UIImage imageNamed:[NSString stringWithFormat:#"EyeAnim%d", i]];
if(anImage) {
[imageView addObject:anImage];
}
}
self.imageDisplay.animationImages = imageView;
self.imageDisplay.animationDuration = 0.25;
self.imageDisplay.animationRepeatCount = 50;
[self.imageDisplay startAnimating];