UITableView - (void)configureView - iphone

I'm working now with table views and detailed views, you know that one which appears when you select element in your table.
there is a method - (void)configureView which is called in viewDidLoad and descriptions say it updates interface.
I've got something like this:
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = self.detailItem;
}
if (self.subjectItem) {
self.subjectLabel.text = [self.subjectItem description];
}
self.imageView.image = self.imageItem;}
my question is: is "description" property required? because it works without it(the first item and imageView), and if so then how syntax would look like for imageView? because "description" is only for NSStrings

Really description is a method of NSObject: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html
You don't need to use it in your code above, neither for NSString.
Just be sure to assign to the properties the correct objects (i.e. self.imageItem must be an istance of UIImage).

Related

Two variables with the same name in different objects altering each others' values

I have two UITableView objects that both have an array named sectionHeaders that is used as a reference object to provide, no surprise, the header names for a given section in the table. The first table view has it as an NSMutableArray and adds the headers dynamically as they are needed. The second view uses an NSArray and creates the array using the #[item1, item2, ...] shorthand. Both objects are declared as global instance variables.
The first table view creates the second and pushes it onto the navigation controller stack. The headers appear correctly the first time the former view is displayed, and they always display correctly whenever the latter view is displayed, but when I hit back to return to the first view, the section headers match those of the second view. This problem is immediately resolved by changing one of the two variable names, but I would much rather understand why the problem is happening in the first place.
Please let me know if any more information would be helpful. I have no concept of what might be causing this, so I'm not entirely sure what information could be useful.
Edit: Here's a simplified version of the way the two objects are set up and interact.
CalendarViewController.m:
NSMutableArray *sectionHeaders;
#implementation CalendarViewController
-(id) initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
sectionHeaders = [[NSMutableArray alloc] init];
}
//this is the method that adds items to the sectionHeaders object with irrelevant information excluded
-(void) distributeEvents {
[self.tableView beginUpdates];
if(condition1) {
if(![sectionHeaders containsObject:#"Today"]) {
[headers addObject:#"Today"];
}
}
else if(condition2) {
if(![sectionHeaders containsObject:#"Next week"]) {
[headers addObject:#"Next week"];
}
}
//et cetera...
}
//the only other time the sectionHeaders object comes up is in
- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return sectionHeaders[section];
}
The second object, an EventViewController, is initialized when a cell is tapped. It is not created with any variables associated with the sectionHeaders object.
EventViewController.m:
NSArray *sectionHeaders;
#implementation EventViewController
//within the init method
sectionHeaders = #[#"What", #"When", #"Where"];
//later...
- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return sectionHeaders[section];
}
That's all the references I make to those objects. I apologize for not having the simplified code in the question to begin with. Hopefully having more context will help.
From your code it appears that both sectionHeaders arrays are defined outside the scope of the corresponding classes and basically are two global variables with same name - in which case linker should have given you a warning.
I suggest you move them inside the class they belong to.

Adding a button to TTTable View Item

I have been banging my head on adding a button to a cell. This is what I have done.
I subclassed TTTableMessageItem and TTTableMessageItemCell.
I added the following method to the Message Item init :
+ (id)itemWithTitle:(NSString *)title caption:(NSString *)caption text:(NSString *)text timestamp:(NSDate *)timestamp imageURL:(NSString *)imageURL URL:(NSString *)URL target:(id)target action:(SEL)action;
I also added a SEL variable and "id" for action and target.
Under setObject in message Item Cell I added this :
- (void)setObject:(id)object {
if (_item != object) {
[super setObject:object];
TJTableMessageItem* item = object;
if (item.plusAction) {
self.plusAction = item.plusAction;
}
if (item.plusTarget) {
self.plusTarget = item.plusTarget;
}
}
}
I am now able to trigger easily a method inside my datasource for the tableview. But I am not able to find out which cell was pressed. I hope someone can help me, I have spent way to much time figuring out the setObject part.
I would like to know how and add a subview like the Facebook app has, the Like, Comment part. I think I need to be able to run a method inside the view controller. But I can't find anything anywhere. The Cybersam blog has an explanation that doesn't use the TableItem and TableItemCell like Three20 puts things up.
assume that the target is your TableViewController, and the the SEL has an argument named sender, like this:
- (void)likeButtonClicked:(id)sender;
then you can find the Cell View according to sender (sender.superView.....), and use the TableView to find the cell's index, that's all.

How to save nsdictionary of a subview to a mainview based off tableviewcell selection

I am currently parsing some xml that looks like this
<Rows>
<Row MANUFACTURERID="76" MANUFACTURERNAME="Fondont" ISMANU="F" ISAUTO="F"/>
<Row MANUFACTURERID="18" MANUFACTURERNAME="Anti" ISMANU="T" ISAUTO="T"/>
</Rows>
I parse it so that there is an array of dictionaries (each dictionary has the four values of the Row in it).
I then pass ManufacturerName to my startSortingTheArray method like this
if (dataSetToParse == #"ICMfg") // ICMfg is a string passed to this view from the parent view cell selection enabling me to pass different data sets to this view
{
//Filter results (ISAUTO = T)
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K like %#",#"ISAUTO",#"T"];
NSArray *filteredArray = [myDataArray filteredArrayUsingPredicate:predicate];
//Passes Manufacturer strigs over to startSortingtheArray method
[self startSortingTheArray:[filteredArray valueForKey:#"MANUFACTURER"]];
}
So from here all of the ManufacturerNames are sent to my method as an array of strings. I then use this array to set up all of my sections / index-scroller. The method below shows how I am doing this.
//method to sort array and split for use with uitableview Index
- (IBAction)startSortingTheArray:(NSArray *)arrayData
{
//If you need to sort incoming array alphabetically use this line of code
//TODO: Check values coming in for capital letters and spaces etc
sortedArray = [arrayData sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
//If you want the standard array use this code
//sortedArray = arrayData;
self.letterDictionary = [NSMutableDictionary dictionary];
sectionLetterArray = [[NSMutableArray alloc] init];
//Index scrolling Iterate over values for future use
for (NSString *value in sortedArray)
{
// Get the first letter and its associated array from the dictionary.
// If the dictionary does not exist create one and associate it with the letter.
NSString *firstLetter = [[value substringWithRange:NSMakeRange(0, 1)] uppercaseString]; //uppercaseString puts lowercase values with uppercase
NSMutableArray *arrayForLetter = [letterDictionary objectForKey:firstLetter];
if (arrayForLetter == nil)
{
arrayForLetter = [NSMutableArray array];
[letterDictionary setObject:arrayForLetter forKey:firstLetter];
[sectionLetterArray addObject:firstLetter]; // This will be used to set index scroller and section titles
}
// Add the value to the array for this letter
[arrayForLetter addObject:value];
}
//Reload data in table
[self.tableView reloadData];
}
from here I do several things to do with setting up the tableview after [self.tableView reloadData]; is called, The main thing being is that I set the cell up with the string values of the array.
//Display cells with data
NSArray *keys = [self.letterDictionary objectForKey:[self.sectionLetterArray objectAtIndex:indexPath.section]];
NSString *key = [keys objectAtIndex:indexPath.row];
cell.textLabel.text = key;
when the cell is then selected the string value inside the cell is then sent back to the main view and used later as a search parameter... The thing being is that I am setting up several parameters that will be used as one search string.
Looking back at the XML I parsed
<Rows>
<Row MANUFACTURERID="76" MANUFACTURERNAME="Fondont" ISMANU="F" ISAUTO="F"/>
<Row MANUFACTURERID="18" MANUFACTURERNAME="Anti" ISMANU="T" ISAUTO="T"/>
</Rows>
These are the values of columns inside an SQl table that has a keyvalue MANUFACTURERID that is also found in other tables that I parse. I would like to use these key values to restrict/refine other queries but I just cannot figure out how to pass them to my parentview where I set up all of the search parameters, that is my question how can I save the dictionary of values that is related to the users tableview selection from the subview. So that I can then pass one or some of those values back to the subview of a different dataset to restrict the information that is displayed dependent on the users previous selections.
This has taken me about an hour to type up. Hopefully it makes sense, I am still fairly new to iOS development and Objective C, and this concept is really pushing my capabilities and before I move on and end up hasing some crap together that I will have to fix later on I am hoping that one or some of you will be able to lend your experience in this type of this to me so I can get this right first time :)
If you need me to clarify anything or provide you more information that will help you help me just let me know.
Thanks in advance!
The common pattern for passing information backwards in your view controller hierarchy is to use delegation. You can achieve this in your scenario by implementing the following:
1) Define a protocol in the SearchParametersViewController, which represents your the parent view controller you mentioned.
#protocol SearchParametersViewControllerDelegate <NSObject>
#optional
- (void)searchOptionsSelected:(NSArray *)selectedSearchOptions;
#end
2) Conform to that protocol in your SearchOptionsSelectionViewController, which represents the table view controller that has a list of selections to choose from. Make sure to import or forward-declare the class the protocol is defined in (e.g. SearchParametersViewController) .
#import "SearchParametersViewController.h"
#interface SearchOptionsSelectionViewController <SearchParametersViewControllerDelegate>
3) Define a delegate property in your SearchOptionsSelectionViewController (assumes you are using ARC on iOS 5.0, 4.x use unsafe_unretained instead of weak. Use assign if the project is using manual memory management). This delegate object will contain a reference to your parent view controller (e.g. SearchParametersViewController). You do not want this property to be retained as to avoid retain cycles/circular references where one object references another, which in turn has a reference back to the first and neither object is ever deallocated.
#property (nonatomic, weak) id<SearchParametersViewControllerDelegate> delegate;
4) When instantiating the SearchOptionsSelectionViewController instance inside your parent view controller (SearchParametersViewController), set the delegate property to the parent view controller instance as represented by the self keyword. This ensures you can send the message (and corresponding data) backward in your view controller hierarchy, yet the object relationships remain loosely coupled. This delegate protocol could be conformed to in any other view controller, there are no tight relationships in the selection view controller back to the parent view controller, the only thing linking them is the flexible delegate protocol adoption by the selection view controller.
SearchOptionsSelectionViewController *selectionViewController = [[SearchOptionsSelectionViewController alloc] init];
selectionViewController.delegate = self;
5) Finally, in your SearchOptionsSelectionViewController table view's -tableView:didSelectRowAtIndexPath: delegate method, pass the data corresponding to the selected row back to your parent view controller (SearchParametersViewController) via the delegate method you defined in the SearchParametersViewControllerDelegate protocol. You must use the -respondsToSelector: method to ensure that the delegate object actually implements the -searchOptionsSelected: delegate method. To force this implementation, change #optional to #required above the method prototype in the protocol definition in step #1. self.someDataArray represents a the data source you are using with the selection table view controller. The specifics of the delegate protocol method and data object(s) sent back to the parent view controller can be changed, the important thing here is the delegation pattern and not having any tightly coupled relationships between the instances of either class, but especially backwards in the view controller hierarchy.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.delegate respondsToSelector:#selector(searchOptionsSelected:)])
{
NSArray *selectedObjs = [NSArray arrayWithObject:[self.someDataArray objectAtIndex:indexPath.row]];
[self.delegate searchOptionsSelected:selectedObjs]
}
}
6) Implement the delegate method inside SearchOptionsSelectionViewController.m
- (void)searchOptionsSelected:(NSArray *)selectedSearchOptions
{
// do what you need to with selectedSearchOptions array
}
Further reading:
Cocoa Fundamentals Guide - Delegates and Data Sources
Cocoa Core Competencies - Protocol
You could use the application delegate to achieve your goals here.
I'm going to assume your app has a structure a bit like this. Please excuse the crudity of this model.
Application delegate (A) --> Search Options View (B) --> Table where you do selections (C)
|
|
--> Some other view where you need the selection (D)
Your problem is that you need information to flow from C to D.
Your application delegate has the merit of being universally accessible via [[UIApplication sharedApplication] delegate]. So you can get a pointer to it from anywhere. From C, you can send your selection information back to A. A can either send this on automatically to D, or D can request it from A whenever it wants it.
A couple of points:
I won't expand any further on my answer at the moment because it's beer o' clock here now, plus I might have misunderstood your requirement. If you do need anything else, I will be up at baby o' clock in the morning UK time so there might be some delay.
Some people frown on using the application delegate as a "data dump" in the way I have suggested. Some of those people would rather set up a whole singleton class and treat that as a data dump instead. It seems to be one of those neverending arguments so I try not to get involved.
You have a few options, one is to use user defaults. It might be the easiest.
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
Another is to post a notification with the information.
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html

Annotation Sub Class custom initWithCoordinate

I've subclassed MKAnnotation so that i can assign objects to each annotation, this is so that when the rightCalloutAccessoryView is clicked i can push a navigation controller with the object passed to it and display the objects data in another view.
This all works great apart from one thing, i've extended upon initWithCoordinate like so:
-(id)initWithCoordinate:(CLLocationCoordinate2D)coord andObject:(NSManagedObject *)object {
[self setPlace:object];
coordinate = coord;
title = [place valueForKey:#"name"];
subtitle = [place valueForKey:#"address"];
return self;
}
Although everything is working great i'm recieving the warning:
NO '-initWithCoordinate:andObject:' method found
Which means i'm doing something wrong somewhere, what is the correct way to go about adding upon initWithCoorinate?
Put the prototype -(id)initWithCoordinate:(CLLocationCoordinate2D)coord andObject:(NSManagedObject *)object in .h file.

tagging a cell for identification in a selected tableview

how is it possible to tag an iphone cell in order to be able to use in a selected favorite table view. i want to be able to tagg the cell and its remaining content in order to be able to display it properly inside a new table view under a different view controller.
You set a tag with a number and by looking at UIView class ref, you set it with an NSInteger,
so a number to you and me.
tableViewCell.tag = 1
Or you extend UITableView and add your own method like
- (void) setFavorite:(BOOL)ans
{
favorited = ans;
}
- (BOOL) favorite
{
return favorited;
}
And then when you access the table view cell, cast it.
Probably better to make it a property though
#property (nonatmoic, assign, getter=isFavorited) BOOL favorited;