How to load a tableView with an array of dictionaries? - objective-c

I want to load a table view with an array which itself has multiple dictionaries. Each of these dictionaries has items which I need to put into a row, one dictionary per row. All of these dictionaries are stored in an array.
How should I perform this task?
Thanks,
See the code below, projects is my array.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return self.projects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
cell.textLabel.text = [self.projects objectAtIndex:indexPath.row];
}

You can do this with pretty much what you have. You'll just need to change your configureCell:atIndexPath: method to look something like this:
cell.textLabel.text = [[self.projects objectAtIndex:indexPath.row] objectForKey:#"some_key"];
Just change some_key to the key in your NSDictionary that you want to display in your UITableViewCell.
You can also change your UITableViewCell style to UITableViewCellStyleSubtitle and then you can add another key from your NSDictionary to cell.detailTextLabel.

In addition to edc1591,
In case if the dictionaries in the array have different keys then
if([[self.projects objectAtIndex:indexPath.row] count]==1)
{
id key= [[[self.projects objectAtIndex:indexPath.row] allKeys] objectAtIndex:0];
cell.textLabel.text = [[self.projects objectAtIndex:indexPath.row] objectForKey:key];
}

Related

sorted by name in sqlite what to return un numberOfRowsInSection

i have sorted my data by name in sqlite:
char*sql="SELECT* FROM tblcocktail ORDER BY drinkname ;";
i dont know how to show it in the table sorted by letters:
please advise :)
-(void)viewDidAppear:(BOOL)animated
{
Cocktails*cock=[[Cocktails alloc]init];
_arrcocktail=[cock getallcocktail];
[self.tableView reloadData];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [_arr count]; //all the letters
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//i don't not what to put here so it will show me the right name under the right letter
}
You can simply create cells and assign names.
In tableView:cellForRowAtIndexPath:
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = [_arr objectAtIndex:indexPath.row];
return cell;
}

connect uitableviewcells to diffrent viws via segue

I create a UITableView programmatically with different cells and sections that connects to the other views in storyboard like below picture:
My question is:
how can I connect these 3 cells to these different views ,would you please helping me
Thanks in advance!
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
[[cell textLabel] setText:contentForThisRow];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selectedIndex = indexPath.row;
[self.tableView reloadData];
}
Edit:
When I use this method It just load the WorkTime view even if user select the absence cell,
Does any one knows why ?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selectedIndex = indexPath.row;
[self.tableView reloadData];
//maybe you could use a switch/case here, to assign the correct string to the segue identifier.
switch (indexPath.row){
case 0:
[self performSegueWithIdentifier:#"test" sender:self];
break;
case 1:
[self performSegueWithIdentifier:#"set" sender:self];
break;
case 2:
[self performSegueWithIdentifier:#"get" sender:self];
break;
}
}
Your last method is the way you want to go, but by the looks of it, you need to be checking indexPath.section not indexPath.row

Howto fill UITableView with sections and rows dynamically?

I have some problems with UITableView and sections/rows.
Iam parsing the section names, all row names and row count per section from a xml.
I have 3 NSMutableArrays:
nameArray (with all row names)
sectionArray (all section names)
secCountArray (row count per section)
For the cellForRowAtindexPath to work, do I have to return the rows for the displayed section?
The next step I would do is to build an 2d Array with sections and all rows for each section.
Does anyone knows any better solution?
Here comes the code:
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Set up the cell
int xmlEntryIndex = [indexPath indexAtPosition: [indexPath length] -1];
//???
cell.textLabel.text = [[theParser.nameArray objectAtIndex: 1]valueForKey:#"name"];
return cell;
}
Thanks!
You could have one _section array and one _row array for the whole tableview.
like your view controller.h file declare array
NSMutableArray *arrSection, *arrRow;
then your view controller.m file paste below code..
- (void)viewDidLoad
{
[super viewDidLoad];
arrSection = [[NSMutableArray alloc] initWithObjects:#"section1", #"section2", #"section3", #"section4", nil];
arrRow = [[NSMutableArray alloc] init];
[arrSection enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSMutableArray *tempSection = [[NSMutableArray alloc] init];
[arrSection enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[tempSection addObject:[NSString stringWithFormat:#"row%d", idx]];
}];
[arrRow addObject:tempSection];
}];
NSLog(#"arrRow:%#", arrRow);
}
#pragma mark - Table view data source
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrSection count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [arrSection objectAtIndex:section];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[arrRow objectAtIndex:section] count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:nil];
if(!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
cell.textLabel.text = [[arrRow objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
return cell;
}
This method does not involve defining and creating your own custom view. In iOS 6 and up, you can easily change the background color and the text color by defining the
- (void)tableView:(UITableView *)tableView
willDisplayHeaderView:(UIView *)view
forSection:(NSInteger)section
delegate method.
For example:
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
// Background color
view.tintColor = [UIColor blackColor];
// Text Color
UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
[header.textLabel setTextColor:[UIColor whiteColor]];
// Another way to set the background color
// Note: does not preserve gradient effect of original header
// header.contentView.backgroundColor = [UIColor blackColor];
}
you can see display dynamic section and row
May be helpful for you..
You could have one array for the whole table view. The array contains arrays for every section. Then the cellForRowAtIndexPath could look like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
[[cell textLabel] setText: [[[myArray objectAtIndex: indexPath.section] objectAtIndex: indexPath.row]];
return cell;
}
I hope this help you in your problem.
Edit: With the modern Objective-C and ARC I would write this as
- (void)viewDidLoad {
....
[self.tableView registerClass:[MyCellClass class] forCellReuseIdentifier:kMyCellIdentifier];
}
...
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
MyCellClass *cell = [tableView dequeueReusableCellWithIdentifier:kMyCellIdentifier forIndexPath:indexPath];
cell.textLabel.text = myArray[indexPath.section][indexPath.row];
return cell;
}

Populating UITableView from NSMutableArray

I am experiencing a strange issue with this code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
if (accounts != nil) {
NSLog(#"Cell: %#", indexPath.row);
cell.textLabel.text = [self.accounts objectAtIndex: indexPath.row];
}
else
{
NSLog(#"No cells!");
[cell.textLabel setText:#"No Accounts"];
}
return cell;
}
My table view populates just fine, except all rows contain the first item in my NSMutableArray, accounts. I am logging the value of indexPath.row and it remains at (null) no matter how many values are in the array. Am I doing something wrong here?
I don't believe this! I am bonking myself on the head for not finding this sooner!
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [accounts count]; //<--This is wrong!!!
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1; // <--This needs to be switched with the error above
}
The above code was the reason why it was printing the same row in my array twice, rather than marching forward in my array.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [accounts count];
}
This code is correct and produces the proper result. What a fuster cluck. ^^;
Should be #"%i", indexPath.row not #"%#", indexPath.row
Also I recommend putting this at the top of your method:
NSUInteger row = [indexPath row];
Then your method looks like this:
// Cell Ident Stuff
// Then configure cell
if (accounts) {
NSLog(#"Cell: %i", row);
cell.textLabel.text = [self.accounts objectAtIndex:row];
}
else {
NSLog(#"No accounts!");
// Only setting for the first row looks nicer:
if (row == 0) cell.textLabel.text = #"No Accounts";
}
It's good practice when dealing with table view methods. Try that.

UITableView save selected items

I need to save selected items for my UITableView in the NSMutableDictionary for iplementing checkboxes. So I do the following:
NSMutableDictionary * selDict;// - instance variable
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([selDict objectForKey:indexPath])
[selDict setObject:[NSNumber numberWithBool:FALSE] forKey:indexPath];
else
[selDict setObject:[NSNumber numberWithBool:TRUE] forKey:indexPath];
[[self tableView]reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
if ([selDict objectForKey:indexPath])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
...
return cell;
}
But it is only sets the items checked and does't work further.
You might want to change
if ([selDict objectForKey:indexPath])
to
if ([[selDict objectForKey:indexPath] boolValue])
What you are doing now is checking whether the object exists or not. It will work once when it is nil but not after that.