Read image name from plist syntax problem? - xcode

I'm trying to read a reference to an image file out of a plist and make the image display in a detail view. although I can do this for my table view layout, I'm having trouble doing this with my DetailViewController nib file. I'm hoping someone can help me fix the problem and explain to me where I'm going wrong. What follows with the code is my explanation of what I THINK I'm doing. If you could explain to me what I'm doing wrong as much as show me what I should be doing, I'd really appreciate it. I'm trying to learn as much as trying to make things work.
I think the problem resides in two places. The first is my didSelectRowAtIndexPath method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get the dictionary of the selected data source.
NSDictionary *dictionary = [[[self.localSites objectAtIndex:indexPath.section]objectForKey:#"rowData"] objectAtIndex:indexPath.row];
TableDetailViewController *controller = [[TableDetailViewController alloc] initWithNibName:#"TableDetailViewController" bundle:[NSBundle mainBundle]];
controller.title = [dictionary objectForKey:#"Location"];
controller.dText = [dictionary objectForKey:#"details"];
// THIS IS WHERE THE PROBLEM IS
NSString *tiny = [dictionary objectForKey:#"thumb"];
controller.mainImage = [UIImage imageNamed:tiny];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
In the code above marked //THIS IS WHERE I THINK THE PROBLEM IS, What I'm trying to do is grab the reference to the image contained in string in the plist and use the reference to get the image. This approach works fine in my cellForRowAtIndexPath method where I use it to populate the left hand side of the table with thumbnail images referred to from my plist.
In the above code mainImage refers to a string I've tried to connect to a UIImageView outlet in my TableDetailViewController.xib through my TableDetailViewController.m file as below. This is where I think Problem number two is:
- (void)viewWillAppear:(BOOL)animated
{
[super viewDidLoad];
//This Bit says that the text contained in UITextView blurb is the string dText, which is used in my didSelectRowAtIndex method
blurb.text = dText;
//This is where I try to do the same thing by saying that UIImageView topImage is the NSString mainImage which I use in my didSelectRowAtIndex method
topImage.image = mainImage;
}
My Logic was that topImage is a UIImageView and mainImage is the string containing the image view which in my didSelectRowAtIndex method I pass the value of the key 'thumb' contained in my plist file.
However the above throws up warnings. Can anyone help?
Thanks for taking the time to read.

Ok, I managed to work this out. My mistake was to declare the pointer mainImage as a NSString instead of as a UIImage. I did this because in the .plist I am using the name of the image is contained within a string. I realised though that as I change this string for the .png file of the same name in my didSelectRowAtIndexPath method, by the time I'm passing it to mainImage it is no longer a string I'm passing, it's an image. Sorted! An easy mistake for a newb like me to make. Thought I should post as I'm sure I wont be the only one who makes this mistake.

Related

AFNetworking and multiple UIImageViews pulling from same URL

I have an issue where im loading 3, sometimes 4 of the same images using
[imageFile setImageWithURL:[NSURL URLWithString:friendAvatar] placeholderImage:[UIImage imageNamed:#"defaultProfileImage.png"]];
Im trying to see if theres a way to load this into some kind of NSData and use it later on, kind of like how im doing below, but using AFNetworking.
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^(void)
{
NSURL *url3 = [NSURL URLWithString:friendAvatar];
NSData *data = [NSData dataWithContentsOfURL:url3];
UIImage *img = [[UIImage alloc] initWithData:data];
dispatch_async( dispatch_get_main_queue(), ^(void){
imageFile.image = img;
bgImageFile.image = img;
});
});
Also im not calling the image loads all in the same method, 2 call under the cellForRowAtIndexPath once the users friends list has been populated, then the 3rd gets loaded when i swipe over a cell to show its hidden (under) layer, the 4th repeat image gets called when pressing a button that is showed once the cell has been swiped which leads to a chatroom view between me and that friend.
Hopefully i got to my point on what im trying to acheive. And any help pointing in the right direction is very much appreciated.
Update:
This is my current code, this is what i mean by im pulling the same image several times.
Inside the cellForRowAtIndexPath
[imageFile setImageWithURLRequest:request placeholderImage:[UIImage imageNamed:#"defaultProfileImage.png"]];
[bgImageFile setImageWithURL:[NSURL URLWithString:friendAvatar] placeholderImage:[UIImage imageNamed:#"defaultProfileImage.png"]];
The method bottomDrawerWillAppear that is called contains
UIImageView *drawerBGImg = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,75)];
NSString *friendAvatar = [NSString stringWithFormat:#"%#%#%#", #"http://v9a2a7.com/user_photos/", [MyClass friendID], #".jpg"];
[drawerBGImg setImageWithURL:[NSURL URLWithString:friendAvatar]];
And on a seperate class and seperate view viewMessageViewController
NSString *friendAvatar = [NSString stringWithFormat:#"%#%#%#", #"http://v9a2a7.com/user_photos/", email, #".jpg"];
[bgImage setImageWithURL:[NSURL URLWithString:friendAvatar]];
I have not confirmed that the viewMessageViewsController's forces the image to be pulled from the server, but i know for a fact on the cellForRowAtIndexPath makes 3 requests for the same image which results in using 3X the amount of data usage
Hope this clears things up.
It sounds like you want to cache the image so you don't have to keep loading it. Assuming that's what you mean...
The AFNetworking method [UIImageView -setImageWithURL:placeholderImage:] already caches this image for you. The second time you call it, the image will be loaded from the cache.
The only reason it would get reloaded from the server a second time is if your app receives a low memory warning since the last download. (AFImageCache, an NSCache subclass, will automatically invalidate some or all of the cache.)
It uses the URL as the key, so as long as the URL is identical, the image will only get loaded from the server once.

Place a background Image behind a grouped UITableView

I've a grouped UITableView which has been resized and rounded. I would like to place a view BEHIND this table.I've tried:
[self.tableView addSubview:backgroundView];
[self.tableView sendSubviewToBack:backgroundView];
but it didn't work. This is what I obtain:
I would like to have the background in place of the black space.
Any idea?
How about [self.tableView setBackgroundView:backgroundView];?
Bear with me I'm a beginner. I just ran into this problem and I found two solutions. In my case, I was using a UITableView object.
To begin, add the background image into your app's directory. I put mine in "Supporting Files"
You can add the image as a UIColor object:
...
[resultsTable setBackGroundColor:setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background.jpg"]]];
...
The problem with this method is that it will repeat your background image because it's treating it as a pattern.
The better way:
// Create a string to store the path location of your image, otherwise you would have to provide an exact path name
NSString *backPath = [[NSBundle mainBundle] pathForResource:#"background"
ofType:#"jpg"];
// Create a UIImage Object to store the image.
UIImage *bgImage = [[UIImage alloc ] initWithContentsOfFile:backPath];
// Create a UIImageView which the TableView
UIImageView *bgView = [[UIImageView alloc]initWithImage:bgImage];
// Set your TableView's background property, it takes a UIView Obj.
[resultsTable setBackgroundView: bgView];
.....

View Based Table Cells on OS X not showing data properly

So I admit to being a total noob to cocoa, so I offer a noob question. I'm probably just missing the dumb obvious somewhere but i just cant seem to get my table to populate data.
I'm following the table view playground example but everytime i try to mimic the Basic TableView Window the first row becomes the height of the number of rows i added (at least thats what it looks like. Here is my code:
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
NSString *identifier = [tableColumn identifier];
if ([identifier isEqualToString:#"filename"]) {
// We pass us as the owner so we can setup target/actions into this main controller object
NSTableCellView *cellView = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
// Then setup properties on the cellView based on the column
cellView.textField.stringValue = [fileList filenameAtIndex:row];
cellView.imageView.objectValue = [[NSWorkspace sharedWorkspace] iconForFile:[fileList fullPathAtIndex:row]];
return cellView;
}
else if ([identifier isEqualToString:#"path"]) {
NSTextField *textField = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
textField.objectValue = [fileList pathAtIndex:row];
return textField;
}
else if ([identifier isEqualToString:#"preview"]) {
NSTextField *textField = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
textField.objectValue = [fileList previewAtIndex:row];
return textField;
}
return nil;
}
I think its worth mentioning that when using a the old school text field cell, I have no problems displaying data (of course the above code is different in that case) so im positive sure its not a problem with my data structure that holds the values. I have also set the correct delegate and data source
The cell using the 'filename' identifier uses the 'image and text table view cell' while the others use just a 'text table cell view'. Neither of them work so i'm guessing something is wrong with how I set my table up. But when comparing my table with that of the example, it's just a spitting reflection (minus identifiers file names).
One thing that I notice that I can't quite figure out is that the example says:
The NSTableView has two reuse identifier assocations: "MainCell" and "SizeCell" are both associated with the nib ATBasicTableViewCells.xib
I don't really understand this statement. However that being said, the example doesn't contain any ATBasicTableViewCells.xib nor does it have any associations with it (code or ib) that I can find.
Have you tried to set the rowSizeStyle of the NSTableView to NSTableViewRowSizeStyleCustom?
[UPDATE] Re-reading your question, it's not clear for me what your problem is. The solution I have given is related to problems with the size of each cell which is not taken into account unless the rowSizeStyle is set to custom.

IOS: NSMutableArray in Viewdidload

in my project I use a NSmutablearray that I fill with UIImageView in .m (viewDidLoad)
arrayView = [[NSMutableArray alloc] initWithObjects: image1, image2, image3, nil];
but in method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
when I write
int i = 1;
[[arrayView objectAtIndex:i] setImage:image];
there is an exception that say that my array is empty...why?
Please post the rest of viewDidLoad. I want to see how image1 is initialized. The line:
arrayView = [[NSMutableArray alloc] initWithObjects: image1, image2, image3, nil];
will return an empty array if image1 is nil. You should also protect your app from crashing by not making assumptions about the data source. You shouldn't crash if the array is empty, just display an empty tableView.
[EDIT]
I just read the last comment you made in the other answer. Sounds like your imageViews are created in IB. Make sure they are connected to the image1 etc outlets in IB.
Try this instead:
if (i < [arrayView count]) {
UIImageView *imageView = [arrayView objectAtIndex:i];
imageView.image = image;
}
Separating accessing the array element (by assigning it to an actual UIImageView object) and then assigning the new image may be helpful. I've seen cases where if you stack up too many operations things get confused, especially if you are dealing with objects of different types that may or may not have the selectors you're using.
Why your array is turning up empty is another issue. Initializing it in viewDidLoad seems right. You may need to add some "protection" (as above) in your table methods to avoid accessing an empty array. Then in method like viewWillAppear:, call reloadData.

componentsJoinedByString gives me EXC_BAD_ACCESS

I have an NSMutableArray i am trying to convert into a string.
Declaring my NSMutableArray...
NSMutableArray *listData;
And later inside a method...
NSString *foo = [listData componentsJoinedByString:#"|"];
NSLog(#"%#",foo);
It seems no matter what i try i keep getting EXC_BAD_ACCESS.
To make sure each element in my array was an NSString i also tried this...
NSMutableArray *mArray = [[NSMutableArray alloc] init];
for (id ln in listData) {
NSString *boo = [NSString stringWithFormat: #"%#",ln];
[mArray addObject:boo];
}
NSString *foo = [mArray componentsJoinedByString:#"|"];
NSLog(#"%#",foo);
I can manipulate my NSMutableArray by adding/deleting objects in the same method or other methods inside my class. But when i try "componentsJoinedByString" the error pops up. Does anyone have any advice or another way i can combine this array into a single NSString?
In the code you've given, there will never be an NSMutableArray for listData. At some point in your code, you'll need to create one, and presumably populate it.
Edit
Okay, so you may get into memory management problems here, so let's be a bit clearer:
You're synthesizing getters and setters for the instance variable, so it's good practice to use those to access it, they'll take care of retain and releasing appropriately.
To set listData you can simply use
self.listData = [listManage getList:[[NSUserDefaults standardUserDefaults] stringForKey:#"list_name"] list:#"LIST"];
or
[self setListData:[listManage getList:[[NSUserDefaults standardUserDefaults] stringForKey:#"list_name"] list:#"LIST"]];
if you prefer.

Resources