Displaying array in uitableview - objective-c

I have an array created like this:
[currentQuizArrayQuestions insertObject:[quizArrayQuestions objectAtIndex:randomIndex] atIndex:0];
How do I access its data to display in the table?
I'm trying this:
NSString *cellValue = [currentQuizArrayQuestions objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
I know it's wrong, but how do I get to the data array object stored in the currentQuizArrayQuestions array.

You need to implement the cellForRowAtIndexPath method. See this tutorial on UITableViews: http://adeem.me/blog/2009/05/19/iphone-programming-tutorial-part-1-uitableview-using-nsarray/
That one uses a UITableViewController, but the idea is the same.
Edit:
To use a different array, do the same thing with the cell for row at index path method, changing the array that the cellValues come from according to what you need. Then call [tableView reload]; which will run through cellForRowAtIndexPath with the contents of the new array.

Related

Updating values on NSArray

I'v run into such problem. I need to update the values in my NSArray. And don't know a way to do it. Here's my array
NSArray *arrayWithInfo = [[NSArray alloc] initWithObjects:AMLocalizedString(#"Status", nil),AMLocalizedString(#"Call", nil),AMLocalizedString(#"Location", nil),AMLocalizedString(#"Control", nil),AMLocalizedString(#"Sim", nil),AMLocalizedString(#"Object", nil),AMLocalizedString(#"Info", nil),nil];
self.dataArray = arrayWithInfo;
[arrayWithInfo release];
To be more specific I have tableview initialized with this array. There is a possibility for user to use different localized strings, so I have to update it. By using [tableview reloadData]; i'v got the table to update, but the values in NSArray stay the same as they were initialized in first place.
So how to make array look up at the strings once again and get their new values?
Use NSMutableArray instead of NSArray
NSMutableArray (and all other classes with Mutable in the name) can be modified.
You should be using an NSMutableArray. Doing so will allow you to change its values after instantiation.
Your array doesn't need to be mutable here as the array seems to be all or nothing. You dont mention the requirement to delete some objects and not others. NSMutableArray isn't needed. You want to write a lazy loading getter method for the array which reinstantiates it if the array doesnt exist.
-(NSArray *)dataArray{
if (_dataArray){
return _dataArray;
}
_dataArray = NSArray *arrayWithInfo = [[NSArray alloc] initWithObjects:AMLocalizedString(#"Status", nil),AMLocalizedString(#"Call", nil),AMLocalizedString(#"Location", nil),AMLocalizedString(#"Control", nil),AMLocalizedString(#"Sim", nil),AMLocalizedString(#"Object", nil),AMLocalizedString(#"Info", nil),nil];
return _dataArray;
}
Then when you want to reload the tableView
self.dataArray = nil;
[tableView reloadData];
this destroys the old array, forcing it to be remade but with the new localisation.
EDIT:
The issue is the array isn't storing the statement AMLocalizedString(#"Status", nil) its storing the result of that statement, which is the localised string itself. There is no way to make the array re-evaluate that statement without either re-creating the whole array again or using an NSMutableArray and changing all the objects. The lazy loading getter method is more in the objective-c style.
You need to use the NSMutableArray. The NSArray is immutable.

Objective-C UITableView index

How do I read always the most upper line (cell.textLabel.text) in a UITableView?
I have two slightly different approaches;
1:
UITableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText2 = cell2.textLabel.text;
NSLog (#" cellText2 = %#", cellText2);
2:
NSMutableString *newidea = [self.array objectAtIndex:indexPath.row];
NSLog (#"newidea = %#", newidea);
Both codes are inside the method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
self.array is same array that fills up the tableView.
The former approach always shows text from the sixth cell. The latter approach always shows text from the fifth cell. In my tableview there is four cells at a time.#
What I want to get is the text from the most upper cell.
I think you have the wrong approach. You don't read values from cells, instead you let the cells read values from your data array. A cell can always have an arbitrary value since they are reused. Even if you have 30 "cells" in your table view there may only be 5 existing actual cells. When a cell goes outside the table view when you scroll, it is moved to the bottom and reused as the next cell. That's why you always have to set the values for each cell on the index path.
Instead you should get the value in the first cell from your data array if you have one. When the table view asks what title the cell att indexPath.row == 0 should have, you give it to it in cellForRowAtIndexPath, for example from an array called "_cellTitles" containing 30 strings for 30 different cells.
If you want to get the text from the "most upper" visible cell, then you can call indexPathsForVisibleRows on the table view. The first object in the returned array is the index path for the most upper visible cell. You can check the string in your array at index indexPath.row.
Example:
NSArray *visibleRows = [self.tableView indexPathsForVisibleRows];
NSIndexPath *firstVisibleCell = [visibleRows objectAtIndex:0];
NSString *firstVisibleCellTitle = [_myDataArray objectAtIndex:indexPath.row];
If you always want to read from first row, instead of indexPath just say 1 there. That way it will always read from the first row.

Objective-c Parse JSON Response

I have been doing a lot of reading but I have not been able to find anything close to what I am trying to do. I am getting a JSON response and populating a UITableView with the results. When the user selects the row on the UITableView I want to grab the corresponding "id" value that is associated with the name displayed. Example JSON response:
{"active":true,"created_at":"2012-05-12T03:04:21Z","description":"Test 1",
"id":11,"name":"This Is A Test","updated_at":"2012-05-12T03:04:21Z"}
So I set the UITableView row with a name of This Is A Test and when the user selects that I want to return the number 11 as being selected. In the didSelectRowAtIndexPath function I can pull the
UITableViewCell *selectedCell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = selectedCell.textLabel.text;
sc.selectedCategory = cellText;
Which will give me the name of the object but how can I call the dictionary again and get the value of "id" where the name matches the selected cell? I am pretty new to objective-c but have been doing java for years. Any examples would be great.
Thanks in advance!
What you have there is a dictionary. You need to cast the Array objectAtIndex (tableview index path) as an NSDictionary object and then use valueForKey.
Something like the following in the didSelectRowAtIndexPath:
NSDictionary *selRow = (NSDictionary *)[myArray objectAtIndex:indexPath.row];
NSInteger myID = [[selRow valueForKey#"id"] intValue];

Trouble setting properties and performing actions on a tableviewcell outside of cellForRowAtIndexPath:

I have a custom tableviewcell that I create a pointer to in the header of my view controller and init inside cellForRowAtIndexPath
if ([[cellOrder objectAtIndex:indexPath.section] isEqualToString:#"balanceCell"]) {
balanceCell = (BalanceCell *) [tableView dequeueReusableCellWithIdentifier:#"balanceCell"];
if (balanceCell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"BalanceCell" owner:self options:nil];
balanceCell = (BalanceCell*) [nib objectAtIndex:0];
}
return balanceCell;
}
I only have one instance of balanceCell in the table view, so I assumed that if I wanted to set any properties of the cell, I could just refer to balanceCell
However, this is not working. When the user presses a button, the method below is called (I verified that it is actually being called). However, the methods called on balance cell don't work.
- (void)addBalanceCell {
[cellOrder addObject:#"balanceCell"];
[table reloadData];
balanceCell.leftEquation = equationCell.leftView.equationOrder;
balanceCell.rightEquation = equationCell.rightView.equationOrder;
[balanceCell setUpText]; // not called
}
What is the proper way to reference balanceCell?
Well this isn't the interface builder way but you should have an array that functions as your datasource.
That datasource should contain the objects that define a BalanceCell.
If you can't manage those objects and reload the table then you might want to consider changing it so.
A UITableViewCell should mainly be used as a View, a means to show the data, Model, that is stored somewhere else aka your datasource.
At the moment you do "addBalanceCell" you should make a new instance of the dataObject and manage your data here. After you manage it with the data you want you can just add if to your datasource and update the table, which means you then made a new cell since there is a new entry in the datasource.
The same way you update these cells by accessing those dataObjects in your datasource. You can ask for the object in your datasource and manage it the way you want it to. If you then update the table the cell should update itself with the new data.
In short, your cell should mainly hold the means to show data, not the data itself.

Get data from a PList into UITableView?

I want to maintain a list of records, for each one I maintain the same type of data. I want to use this data in 2 different places:
UITableView that takes from each record the "Name" value
UIViewController that takes all the data to use in different fields.
I assume I should be using a plist to store the data; I also assume that the object that should be receiving the data for the UITableView is NSArray so I can use the cellForRowAtIndexPath method to create the table automatically.
So i created the plist "PLForArr.plist":
It seems that i can only get a NSDictionary when calling the plist using
NSString *path = [[NSBundle mainBundle] pathForResource:#"PLForArr" ofType:#"plist"];
NSArray * myArr = [[NSArray alloc] initWithContentsOfFile:path]; //doesn't work...
NSDictionary * myDict = [[NSDictionary alloc] initWithContentsOfFile:path]; //does work, but who to I make a NSArray out of it / or get the data from here to the UITableView?
I understand that i don't understand something basic here... Can someone take me step by step on:
How to keep the data - should I use plist or something else? Should I have a main record of type array (as I did on the example plist here) or can I just keep it as these Dictionaries without the unnecessary MyArr that I used considering the UITableView end target?
How to call the data - Is there a way to get it into a NSArray or must it get into a NSDictionary?
How to call it into the the UITableView - Can I fill in the lines using a NSDictionary?
Storing the data is an Array or a Dictionary is up to you. But if you want to make changes to it over time you can't store it in the main bundle.
Your pList file is a dictionary that contains an array. See code example below.
You will have to store the dictionary in an array for the data source for your table. See code example below.
Assuming that your UITableView's data source is called tableArray. You can use tableArray to fill in the information in the table and your view. Oh yeah,
NSString *path = [[NSBundle mainBundle] pathForResource:#"PLForArr" ofType:#"plist"];
NSDictionary *myDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *myArray = [myDict objectForKey:#"MyArray"];
self.tableArray = [myArray copy];
[myArray release];
[myDict release];
This goes in tableView: cellForRowAtIndexPath:
cell.text = [[tableArray objectAtIndex:row]objectForKey:#"Obj Name"];
Storing your data either in a dictionary, or in an array is up to you. Depending on the kind of data you have, you will consider storing unordered collection of objects (dictionary), accessing the entries with keys; or rather in ordered collection (array), using numeric indexes.
It's fine to get arrays from property list files, but the root (top level) object is a dictionary (in the screenshot, "MyArr" isn't the top-level object, it is the key for accessing your array in the top-level dictionary). To get your array from it, simply alloc/init the plist dictionary the way you did, and access the array entry using its key ([myDict objectForKey:#"MyArr"]). Otherwise make sure you set the root object of the property list to be an array, and retry NSArray's initWithContentsOfFile:
The real question seems to be How can I fill the cells with my data ? The table views ask its delegate and dataSource about how many sections, rows in a section, to display. Based on these numbers, it will ask the dataSource for cells. Once again depending on the storage type you've chosen, you will implements these methods a little bit differently, but the concepts remain.
You will probably want to read documentation about :
Property List
Table views