Access an array and get the stringvalue of an element - iphone

i would like to know how i can access the name of an image when the syntax is something like that:
NSArray* imgArray =[[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"test_01.png"],
[UIImage imageNamed:#"test_02.png"],
[UIImage imageNamed:#"test_02.png"], nil];
If i print out a specific index, i get the address.
NSLog(#"TEST: %#", [imgArray objectAtIndex:1]);
Output:
TEST: <UIImage: 0x4b12cd0>
How do i get the stringvalue?
Any ideas?
Thanks for your time.

UIImage does not expose the name of file it was initialized with. There is no way to access it from the image object.

You should keep track of the string values yourself. The UIImage object is somewhat closed with respect to the data backing the image.
You could of course subclass UIImage and implement
+(UIImage*)imageNamed:(NSString*)name
{
self.keepName = name;
return [super imageNamed:name];
}
adding a keepName string property, but I wouldn't see why you would.

If you want to store & retrive image from NSMutableArray than you have to take your image in UIimageView and than store it in NSMutableArray.. and from particular index you can retrieve it back.
K.D

Related

how to show images at cell.imageview.image from NSArray?

Image Array=[NSArray arrayWithObjects:[UIImage imageNamed:#"1 (1).gif"],
[UIImage imageNamed:#"1 (2).gif"],[UIImage imageNamed:#"1 (3).gif"],[UIImage imageNamed:#"1 (4).gif"],[UIImage imageNamed:#"1 (5).gif"],[UIImage imageNamed:#"1 (6).gif"],[UIImage imageNamed:#"1 (7).gif"],nil];
//here is another array of objects showing in table view
alphabetsArray =[[NSMutableArray alloc]initWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z",nil];
//everything working fine until when i add this code,app crashes with SIGABRT
cell.imageView.image=[UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]];
Actually i need to ask some more things:
Is there any problem if number of images in array isn't equal to number of object in tableview?
Is there any other way to add images if they are huge in number except of uiimage imageNamed:"whatever.jpeg"
What if add a folder and give its address or name and it picks up images by itself..
What is most reasonable method of adding images in project if they are 250 in number(i-e sqlite,coreData,hardcode in project as i did)?
First, there is issue with this line [UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]].
The [imageArray objectAtIndex:indexPath.row] is returning UIImage object in your current implementation, and you are trying to get UIImage with name of UIImage object.
You should just return the UIImage object directly to the cell.imageView.image.
cell.imageView.image = [imageArray objectAtIndex:indexPath.row];
Second, I am not sure how many rows are there in the table, but the method objectAtIndex can throw exception if the index is more than the number of elements in the array, causing app crash.
1) There would be no problem with this, unless you want to have the same number. It won't throw an error, but your app logic will not work properly.
2) Not that i know of, It's easy to do this though, use an easy naming convention such as image01, That way you can just copy and paste the code and change the ending numbers of the image
3) Im not sure of what you are asking.
4) Typically you would just need to add the images to your project via drag-N'-drop or by picking the files. Core data and sqlite are for the actual app that you are developing, not to store images in Xcode.
As for the main question, You say you want to show the images from an NSArray, if thats the case, just get the index path of the tableview, and look up the corresponding image using objectAtIndex:
Hope that helps a bit :)
Actually i have figured something out , there is an easy way to do.
cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#.gif", [TextShownInTableArray objectAtIndex:indexPath.row]]];
i have alphabetics in this array, and i wanted to use different images with each of the alphabet, so just added images in project with same name as alphabets had. it worked fine with this line of code. TextShownInTableArray is your array with text :)
Image Array=[NSArray alloc]initWithObjects:[UIImage imageNamed:#"8.gif"],
[UIImage imageNamed:#"2.gif"],[UIImage imageNamed:#"3.gif"],[UIImage imageNamed:#"6.gif"],[UIImage imageNamed:#"5.gif"],[UIImage imageNamed:#"4.gif"],[UIImage imageNamed:#"7.gif"],nil];
your array alloc and that array 'retain' this array and try this code .thanks
[imageArray retain];
only change in your code this line . and solve your problem
cell.imageView.image=[imageArray objectAtIndex:indexPath.row];
i hope this code useful for You . Check this
cell.imageView.frame = CGRectMake(5, 5, 50, 50);
NSString *imgstr = [[Arr objectAtIndex:indexPath.row] objectForKey:#"thumb"];
cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imgstr]]];

Populating Data from NSMutableArray in iPhone

I have three arrays and I have copied all these arrays into a single array. All these three arrays are arrays of dictionaries.All arrays has a field called picture, but that pictures is coming from different sources- URL in one array, data in other and files in the third one.
Say, Array1 has dictionaries with a key - picture and its loaded from NSURL.
Similarly, Array2 and Array3 has dictionaries with same key name - picture and loaded from ContentofFiles and NSData.
Now, I want to populate tableview, of course,m having Custom UITableViewCell, it has image view as its content view. To load that image, what should I do.
I was doing this thing..
NSURL *url = [NSURL URLWithString:[[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"]];
cell.contactImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
But, this will crash if cell.contactImageView.image don’t receive image from NSURL.So, what should I do? Any help, will be appreciated
But,
all you is to check if the received image is null and if it is, then set a template photo image called no photo like a photo on facebook when no profile picture is selected
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
if (img)
cell.contactImageView.image = img;
else
cell.contactImageView.image = [UIImage imageNamed:#"no_photo.png"];
If these images are retrieved from the net, i would suggest not using [NSData dataWithContentsOfURL:].
You should be using a non blocking method, that loads images asynchronously. Using this method on numerous rows in a table will cause performance issues.
Here's my recommendation , use the SDWebImage Library . Easy to use, and even easier to install.
Once you add the library to your project, simply #import the UIImageView+WebCache.h class usage example is below.
[cell.contactImageView.image setImageWithURL:[NSURL URLWithString:[[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
You can add one more key in dictionary which will specify from where to take photo and accordingly you can provide image to cell.contactImageView, if you want to provide image from different sources.
Thanks a lot buddies for your Quick reply,especially #skram, due to your suggestion,my tableview performance has increased much. the Question, that I have asked,the better answer that I have thought of is using iskindofClass. If image is coming from any class, on a condition ,we can check from where that image was coming and populate our image accordingly.
if ([[[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"] isKindOfClass:[UIImage class]])
{
cell.contactImageView.image = [[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"];
}
else if ([[[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"] isKindOfClass:[NSString class]])
{
cell.contactImageView.image = [[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"];
}
else if([[[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"] isKindOfClass:[NSURL class]])
{
[cell.contactImageView setImageWithURL:[NSURL URLWithString:[[contactList objectAtIndex:indexPath.row] objectForKey:#"picture"]]placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
}
Now, I’m able to populate the tableview properly.Once again thanx to scram.

Memory problem with properties in objective-c

UIImage *image = [[UIImage alloc] initWithData:data];
((YKSubCategory *)[_subCategories objectAtIndex:connection.tag - 1]).menuImage = image;
[image release];
Here is the code I've written. The data is exists and the designed image is created. (I've tested it with an imageview and the image appears).
The problem comes when I try to set the menuImage property. It will not be set. I don't know why. So the value of the menuImage property remains nil.
Here is the property definition:
#property (nonatomic, retain) UIImage *menuImage;
What can be the problem?
Edit:
I've divided the code for the request of walkytalky.
Here is the code I've written:
UIImage *image = [[UIImage alloc] initWithData:data];
YKSubCategory *subCategory = (YKSubCategory *)[_subCategories objectAtIndex:connection.tag - 1];
subCategory.menuImage = image;
[image release];
[_tableView reloadData];
So now the funny thing is that the subCategory variable is the variable what I expect. Then after I set the menuImage property then the variable for this property is set. I can see in the debugger, but in the array isn't set. What is this?
(i) Have you #synthesize-d menuImage?
(ii) Can you break up the setter line to first get the YKSubCategory object and test it exists and is what you expect?
YKSubCategory* target = (YKSubCategory*)[_subCategories objectAtIndex:connection.tag - 1];
NSLog("subcategory target = %#", target);
// other tests here
target.menuImage = image;
Otherwise, I don't think we have enough info to solve this. What does menuImage look like immediately after setting?
EDIT: when you say "in the array isn't set", do you mean that the actual object in the array differs from the one you've just set right there and then? Or that when you come back to the array when loading the table data the menuImage is no longer set? Or that it just doesn't show in the table?
The first seems impossible on the face of it, so let's think about the second and third.
If menuImage has been reset by the time you come back to it, there must be some code setting it somewhere. This may not go through the property accessor, but for starters you might explicitly implement the setter to log the changes:
- (void) setMenuImage:(UIImage*)newImage
{
if ( newImage != menuImage )
{
NSLog(#"Changing menuImage from %# to %#", menuImage, newImage);
[newImage retain];
[menuImage release];
menuImage = newImage;
}
}
Another possibility is that the actual YKSubCategory object in the array has changed, or even that the arrays are different, so check that the pointers are the same in both locations.
On the other hand, if the menu image ivar is set, but it's not showing up in the table, you need to check your drawing code.

To store images from UIGetScreenImage() in NSMutable Array

I'm getting images from UIGetScreenImage() and storing directly in mutable array like:-
image = [UIImage imageWithScreenContents];
[array addObject:image];
[image release];
I've set this code in timer so I cant use UIImagePNGRepresentation() to store as NSData as it reduces the performance. I want to use this array directly after sometime i.e after capturing 1000 images in 100 seconds. When I use the code below:-
UIImage *im = [[UIImage alloc] init];
im = [array objectAtIndex:i];
UIImageWriteToSavedPhotosAlbum(im, nil, nil, nil);**
the application crashes.
And I dont want to use UIImagePNG or JPGRepresentation() in timer as it reduces performance.
My problem is how to use this array so that it is converted into image.
If anybody has idea related to it please share with me.
You don't need to release the image in your first code sample there. [UIImage imageWithScreenContents] returns an autoreleased object.
1. UIImage *im = [[UIImage alloc] init];
2. im = [array objectAtIndex:i];
3. UIImageWriteToSavedPhotosAlbum(im, nil, nil, nil);
Line 1 allocates and initializes a new UIImage object, which never gets released since you overwrite the pointer on line 2. You are leaking an UIImage in each iteration, and you don't even need to init/alloc a new object.
UIImageWriteToSavedPhotosAlbum([array objectAtIndex:i], nil, nil, nil);
Should work just fine.
Also note Carl Norum answer about releasing an autoreleased object.

Using a variable in a statement to reference the image stored in a UIImageView

UPDATED Scroll down to see the question re-asked more clearly....
If I had the name of a particular UIImageView (IBOutlet) stored in a variable, how can I use it to change the image that is displayed. I tried this, but it does not work.
I'm still new to iphone programming, so any help would be appreciated.
NSString *TmpImage = #"0.png";
NSString *Tst = #"si1_1_2";
TmpImage = #"1.png";
UIImage *sampleimage = [[UIImage imageNamed:TmpImage] retain];
((UIImageView *) (Tst)).image = sampleimage; // This is the line in question
[sampleimage release];
RESTATED:
I have a bunch of images on the screen.... UIImageView *s1, *s2 ,*s3 etc up to *s10
Now suppose I want to update the image each displays to the same image.
Rather than doing
s1.image = sampleimage;
s2.image = sampleimage;
:
s10.image = sampleimage;
How could i write a for loop to go from 1 to 10 and then use
the loop var as part of the line that updates the image.
Something like this.
for ( i = 1; i <- 10; ++i )
s(i).image = sample; // I know that does not work
Basic question is how do I incorporate the variable as part of the statement to access the image? Don't get hung up on my example. The main question is how to use a variable as part of the access to some element/object.
Bottom Line... If I can build the name of a UIImageView into a NSString object, How can I then use that NSString object to manipulate the UIImageView.
Thanks!
Ugh! Your line in question:
((UIImageView *) (Tst)).image = sampleimage;
is casting a string pointer as a UIImageView pointer - you're basically saying that your pointer to a string is actually a pointer to a UIImageView! It will compile (because the compiler will accept your assertion happily) but will of course crash on running.
You need to declare a variable of type UIImageView. This can then hold whichever view you want to set the image of. So your code could look like the following:
NSString *TmpImage = #"0.png";
UIImageView *myImageView;
If (someCondition == YES) {
myImageView = si1_1_2; //Assuming this is the name of your UIImageView
} else {
myImageView = si1_1_3; //etc
}
UIImage *sampleimage = [UIImage imageNamed:TmpImage]; //no need to retain it
myImageView.image = sampleImage;
Hopefully this makes sense!
Edit: I should add, why are you trying to have multiple UIImageViews? Because a UIImageView's image can be changed at any time (and in fact can hold many), would it not be better to have merely one UIImageView and just change the image in it?