problem with UiImageView.image = nil - objective-c

.h file
#interface AppViewController : UIViewController {
...
UIImageView *imageViewArray[3][5];// not using any #property for this
...
}
...
#define FOR(j,q) for (int j = 0; j < q; j++)
.m file
ViewDidLoad{
FOR(i,5){
FOR(j,3)
{
image_names[0] = [UIImage imageNamed:[NSString stringWithFormat:#"%d.png",j]];
imageViewArray[j][i] = [[UIImageView alloc] initWithImage: image_names[0]];
CGRect newFrame ;
newFrame = CGRectMake(60+(j*130), 110+(150*i),130,136);
imageViewArray[j][i].frame = newFrame;
[self.view addSubview:imageViewArray[j][i]];
}
}
}
//clear the previous images and call a method to add new
-(IBAction)Change{
FOR(i,5)
FOR(p,3)
imageViewArray[p][i].image = nil;
[self ImageSwitch];
}
-(void)ImageSwitch{
FOR(i,5){
FOR(j,3)
{
image_namesTmp[0] = [UIImage imageNamed:[NSString stringWithFormat:#"%d.png",j+3]];
imageViewArray[j][i] = [[UIImageView alloc] initWithImage: image_namesTmp[0]];
CGRect newFrame ;
newFrame = CGRectMake(60+(j*130), 110+(150*i),130,136);
imageViewArray[j][i].frame = newFrame;
[self.view addSubview:imageViewArray[j][i]];
}
}
}
when i press the button for the first time it works fine(old images get replaced with new ones),but if i do it second time
imageViewArray[p][i].image = nil;
this line wont work and all the previous images still remain there and new images are overlapping with the present ones

In the ImageSwitch method you are always creating new instances of UIImageView.
imageViewArray[j][i] = [[UIImageView alloc] initWithImage: image_namesTmp[0]];
At this point, there already is a reference to UIImageView stored in the variable. You are losing your reference to it and since you alloc/inited it, you will most probably also leak its memory. Moreover, you are adding new UIImageViews to the view hierarchy, but you are not removing the old ones.
Try something like this:
[imageViewArray[j][i] removeFromSuperview];
[imageViewArray[j][i] release];
imageViewArray[j][i] = [[UIImageView alloc] initWithImage: image_namesTmp[0]];

Second time you set your images you don't need to recreate the UIImageView objects. Your ImageSwitch method is better declared as,
-(void)ImageSwitch{
FOR(i,5){
FOR(j,3)
{
imageViewArray[j][i].image = [UIImage imageNamed:[NSString stringWithFormat:#"%d.png",j+3]];
}
}
}
Just changing the images will suffice and that's what you need to do.

You need an NSMutableArray of ImageViews. In your header declare the NSMutableArray:
NSMutableArray *_imageViewArray;
Then in your viewDidLoad method initialize the array and then populate it with your image views.
_imageViewArray = [[NSMutableArray alloc]init];
for (int i =0; i < imageNames; i++) {
UIImageView *tempImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:[imageNames objectAtIndex:i];
[_imageViewArray addObject:tempImageView];
[tempImageView release];
}
So thats the image view array populated, you may do it a different way but thats up to you.
To switch the views over what I would do is like so...
[self.view removeAllSubviews]; // gets rid of all previous subviews.
[self.view addSubview:[_imageViewArray objectAtIndex:3]];// could be any number. generate a random number if you want.
Thats all you would need to do. If you wanted to know which image view was being displauyed the maybe declare an instance of UIImageView in your header called _currentImageView and then you can remove just that image view instead of all subviews.
Hope this helped.

Related

UIScrollView with UIViews not shown

I'm trying to use a UIScrollView with UIViews (to manage them as xib files), for now I have an array where I store the views.
testingView is a UIViewcontroller with his own xib file and testingView2 is also an UIViewcontroller with his own different xib file
- (void) viewDidLoad {
[super viewDidLoad];
_testingView = [[TestingViewController alloc] init];
_testingView2 = [[TestingViewController2 alloc] init];
self.array = [[NSArray alloc] initWithObjects: _testingView.view, _testingView2.view, nil];
for (int i = 0; i < [array count]; i++) {
CGRect frame;
frame.origin.x = self.scrollingView.frame.size.width*i;
frame.origin.y = 0;
frame.size = self.scrollingView.frame.size;
[self.scrollingView addSubView: [self.array objectAtIndex:i]];
}
self.scrollingView.contentSize = CGSizeMake (_scrollingView.frame.size.width*[array count], _scrollingView.frame.size.height);
}
the problem is that he is taking only the first view (even if I switch them) and the second view is not shown, the same with UIImages instead of views is working, can someone explain me why? seems like he is not seeing the second view in the array order...
Why are you calculating the variable "frame" inside the for loop when you are not using it?
In my view you should make the following change to your code.
for (int i = 0; i < [array count]; i++) {
CGRect frame;
frame.origin.x = self.scrollingView.frame.size.width*i;
frame.origin.y = 0;
frame.size = self.scrollingView.frame.size;
**UIView *v=[self.array objectAtIndex:i];**
**v.frame=frame;**
**[self.scrollingView addSubView:v];**
}
Hope it works.
In the for loop, you calculate frame for newly added subview, but you don't set that frame to that subview.
In your loop, add your subview like this for example:
UIView *subview = (UIView *)[array objectAtIndex:i];
subview.frame = frame;
[self.scrollingView addSubView:subview];
You need to set the frame for each of the subviews in the scrolling view. For example, you can set the frame of _testingView2.view to be the offset of x from the _testingView1.view frame width.
_testingView2.view.frame = CGRectOffset(_testingView2.frame, CGRectGetWidth(_testingView1.frame), 0)
There are many ways to calculate the frame. Try to use the methods CGRectWidth, CGRectGetMaxX, etc.

UIPageViewController - view doesn't load

I want to load a UIView as the first page and some UIImageViews after that. The UIImageViews load fine, but the first UIView shows blank.
I designed the UIView in storyboard. It has some UIButtons and few other controls. What am I doing wrong?
I created the project from the default pageController template.
ModelController.m
- (id)init
{
self = [super init];
if (self) {
// Create the data model.
/*
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
_pageData = [[dateFormatter monthSymbols] copy];
*/
NSMutableArray *imageViews = [[NSMutableArray alloc] init];
FirstViewController *firstViewController = [[FirstViewController alloc] init];
firstViewController.view.frame = CGRectMake([UIScreen mainScreen].bounds.origin.x,[UIScreen mainScreen].bounds.origin.y,[[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width);
[imageViews addObject:firstViewController];
for (int i=1; i<=19; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"picture%i.jpg", i]]];
imageView.frame = CGRectMake([UIScreen mainScreen].bounds.origin.x,[UIScreen mainScreen].bounds.origin.y,[[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width);
[imageViews addObject:imageView];
}
_pageData = imageViews;
}
return self;
}
- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard
{
// Return the data view controller for the given index.
if (([self.pageData count] == 0) || (index >= [self.pageData count])) {
return nil;
}
// Create a new view controller and pass suitable data.
DataViewController *dataViewController = [storyboard instantiateViewControllerWithIdentifier:#"DataViewController"];
dataViewController.dataObject = [self.pageData objectAtIndex:index];
if(index == 0)
{
//[dataViewController addChildViewController:[self.pageData objectAtIndex:index]];
FirstViewController *firstViewController = [self.pageData objectAtIndex:index];
[dataViewController.view addSubview:firstViewController.view];
}
else
{
UIImageView *imageView = [self.pageData objectAtIndex:index];
[dataViewController.view addSubview:imageView];
}
return dataViewController;
}
You haven't provided enough context to be certain, but it appears that what you need to load from the storyboard initially is an instance of FirstViewController, not an instance of UIView, so you'd need to do something like this instead of what you're currently doing:
FirstViewController *firstViewController = [self.storyboard instantiateInitialViewController];
// Note: If you need to adjust the frame of the controller's view, use the screen's
// application frame rather than its bounds.
controller.view.frame = [UIScreen mainScreen].applicationFrame;
Also, this seems like a bad idea, since you later fill the rest of the array with instances of UIImageView:
[imageViews addObject:firstViewController];
Why not add the controller's view to the array? Then you could eliminate the conditional logic in your viewControllerAtIndex:storyboard: method. Also, it's not clear why you're passing the storyboard in as an argument rather than using the built-in property, or for that matter, what class the code you posted belongs to, and what its relation is to the rest of your app. Maybe you could provide a little more info about that.
I got it to working by adding a xib file for FirstViewController. What ever I design in the xib shows up well. Previously I was designing it in the storyboard.

Cocoa Touch: Adding images in for loop

this is crashing on me when I put in an array of image urls, I think its because of me creating the UIImageView and then trying to do it again with the same name!
- (void)cycleImages:(NSArray *)images {
int fromLeft = 5;
for(int n = 0; n <= [images count]; n++){
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[images objectAtIndex:n]]]]];
myImageView.frame = CGRectMake(fromLeft, 5, 48, 48); // from left, from top, height, width
fromLeft = fromLeft + 53;
//add image view to view
[self.view addSubview:myImageView];
NSLog(#"%#", [images objectAtIndex:n]);
}
}
Any ideas?
Thanks!
Dex
First, you should use fast enumeration instead of an index loop. Fast enumeration is simpler, clearer, and faster—whenever you don't specifically need an index for something, there is no reason not to use fast enumeration.
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[images objectAtIndex:n]]]]];
This assumes that [images objectAtIndex:n] is a string. Is that what you put into the array?
Also, because you created that image view with alloc, you need to release it. If you're using ARC, that's done automatically, so you don't need to do anything; otherwise, you need to either send it release after adding it as a subview or send it autorelease.
this is crashing on me …
Please be more specific. What sort of “crash” do you get, and on what line?
If you get a crash log, please edit your question to include it.

How to add a UIImageView to a UIView (not a UIViewController)?

I created view-based application.
I have got a sampleGameViewContrioller.xib, which contains main View, and child View, which connected with class Behavior.
SampleViewController.xib:
View
View <- Behavior
In sampleViewContoller.m I create instance of the class Behavior:
Behavior *b = [[Behavior alloc] initilizeWithType:#"type" position:rect mapArray:arrMap];
Behavior.m:
-(id) initilizeWithType:(NSString *)type position:(CGRect) pos mapArray:(NSMutableArray *) mapArr {
self = [super initWithFrame:CGRectMake(0, 0, 1024, 570)];
if (self != nil) {
if ([type isEqualToString:#"type"]) {
arrMap = mapArr;
self.rectForDraw = pos;
self.file = [[NSString alloc]initWithString:#"girl.png"];
UIImageView *imgg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"girl.png"]];
imgg.frame = rect;
[self addSubview:imgg];
timer = [NSTimer scheduledTimerWithTimeInterval:0.015 target:self selector:#selector(moving:) userInfo:nil repeats:YES];
}
}
return self;}
But it doesn't work. Image doesn't add to my View.
if I add imageView in -(void)drawRect:(CGRect) rect, it's working:
- (void)drawRect:(CGRect)rect {
self.img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"girl.png"]];
self.img.frame = CGRectMake(100, 100, 100, 100);
[self addSubview:self.img]; }
But i should send parameters of drawing in class Behavior through constructor. How to add imageView without method drawRect, with my constructor?
sorry for my English :)
If u want to add an image view over simple UIView then just do [self.view addSubview:imageview]; If you are getting that Image from Behaviour class method then return UIImageView from that method and the add it to your view
Try this:
Behavior *b = [[Behavior alloc] init];
Then write one method in Behaviour class
-(UIImageView*) initilizeWithType:(NSString *)type position:(CGRect) pos mapArray:(NSMutableArray *) mapArr {
// Your Logic
return imgView; //UIImageView object
}
Then call this method in your viewcontroller as
UIImageView *imgView=[b initilizeWithType:#"YOUR STRING" position:YOUR RECT pos mapArray:YOUR ARRAY ];
imgg.frame = rect;
This line assigns your imageView frame to... nothing as far as I can see. Should this be pos or rectForDraw? When adding to your view in drawRect you are explicitly setting a real frame so this is probably where the difference lies.

Cocoa Touch - Adding a UIImageView programmatically?

How can I create and position a new imageview in objective-c?
Thanks!
I tried this but it doesnt seem to do anything...
-(void)drawStars{ //uses random numbers to display a star on screen
//create random position
int xCoordinate = arc4random() % 10;
int yCoordinate = arc4random() % 10;
UIImageView *starImgView = [[UIImageView alloc] initWithFrame:CGRectMake(xCoordinate, yCoordinate, 58, 40)]; //create ImageView
starImgView.image = [UIImage imageNamed:#"star.png"];
[starImgView release];
I placed this method in my viewcontroller. I see some CG stuff do I need to import core graphics or something? (what is core graphics anyway?)
You are asking about iPhone image view. Right? Then try this
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 100, 50)];
This will create an image view of 100 x 50 dimension and locating (10, 10) of parent view.
Check the reference manual for UIImageView and UIView. You can set an image by using image property of imageView.
imgView.image = [UIImage imageNamed:#"a_image.png"];
And you can use the contentMode property of UIView to configure how to fit the image in the view. For example you can use
imgView.contentMode = UIViewContentModeCenter to place the desired image to the center of the view. The available contentModes are listed here
You haven't added your view as a subview to another view, meaning it isn't in the view hierarchy.
Assuming you are doing this in a view controller, it might look something like:
[self.view addSubview: imgView];
(void)viewDidLoad {
[super viewDidLoad];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.layer.frame.size.width, self.view.layer.frame.size.height)];
imgView.image = [UIImage imageNamed:#"emptyCart.jpeg"];
imgView.backgroundColor = [UIColor whiteColor];
imgView.contentMode = UIViewContentModeCenter;
[self.view addSubview: imgView];
}
I had problem with passing the value NSSArray to NSString,
I got the answer:
//Display all images....
NSString *imgstring= [self.allimages objectAtIndex:indexPath.row];
cell.myimages.image=[UIImage imageNamed:imgstring]; //displaying Images in UIImageView..noproblem.
// Display all numbers...
cell.mylables.text=[NSString stringWithFormat:#"%#", [mysetobjectAtIndex:indexPath.row ]]; //showing results fine ArghyA..