I have an app that has a lot of views including tableViews but one of them has a problem that I don't know how to solve.
When the constructor of the cell is called:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
the parameter cellForRowAtIndexPath:(NSIndexPath *)indexPath get a random and strange number. I'm building this tableView in the same way as others. Somebody has any idea about what is happening?
Thanks,
Claudio
The trick to indexPath is using the UITableView extention properties indexPath.section and indexPath.row.
In other words if you have a simple list of string:
self.data = [NSArray arrayWithObjects:#"One", #"Two", #"Three", nil];
then in tableView:cellForRowAtIndexPath: you want to do:
cell.textLabel.text = [self.data objectAtIndex:indexPath.row];
If you have an Array within an Array:
self.data = [NSArray arrayWithObjects:
[NSArray arrayWithObjects:#"A.1", #"A.2", nil],
[NSArray arrayWithObjects:#"B.1", #"B.2", nil],
nil];
Then you'll want to check the section and row property:
NSArray *strings = [self.data objectAtIndex:indexPath.section];
cell.textLabel.text = [strings objectAtIndex:indexPath.row];
Make sure you return the right numbers for numberOfSectionsInTableView: and tableView:numberOfRowsInSection:.
Related
I'm working on information retrieval where in the latest information in on top of UITableView. The code goes like this.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LoanModel* loan = _feed.products[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" ];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:#"Cell"];
}
NSString *myString = [NSString stringWithFormat:#"%#",[loan name]];
NSArray *myWords = [myString componentsSeparatedByString:#","];
NSMutableArray *reversed = [NSMutableArray arrayWithCapacity:[myWords count]];
NSEnumerator *enumerator = [myWords reverseObjectEnumerator];
for (id element in enumerator) {
[reversed addObject:element];
}
NSMutableString *reverseString = [reversed componentsJoinedByString:#","];
cell.textLabel.text = reverseString;
return cell;
}
I'm getting the JSON object which contain two fields cid and name respectively. I'm showing only the name is tableview. But I want to show it in reverse i,e last update should show at first. But above code showing the content in reverse. IF "hello" is the content, then it shows "olleh". Please suggest me how to get the UITableView in reverse list. I'm a newbie to iOS.
If you want to have the reversed order of cells / objects they represent, you have to change
LoanModel* loan = _feed.products[indexPath.row];
to
LoanModel* loan = _feed.products[_feed.products.count - 1 - indexPath.row];
assuming that _feed.products is an NSArray.
The array you are using to display the the data in tableView, you'll need to reverse that and then display the data in tableView
NSArray* reversed = [[myArray reverseObjectEnumerator] allObjects];
you can use this to make your array objects order in reverse.
Try This:
NSArray* reversedArray = [[myWords reverseObjectEnumerator] allObjects];
I am creating a static table view (must be compatible with iOS 4 - so I can't use iOS 5's method).
The way I have it is that I have two sections; the first has one cell, and the second has two cells. I made two arrays, one with the title of the only cell in the first section, and the second with both titles for both cells in the second section. So my dictionary looks like this:
(NSDictionary *) {
First = (
Title1 < --- Array (1 item)
);
Second = (
"Title1", < --- Array (2 items)
Title2
);
}
The issue I have is that I need to return number of rows in a section using tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section. So my question is, how do I retrieve the section from the dictionary using NSInteger section? I would also have to do the same thing in tableView:cellForRowAtIndexPath.
Thank you
If you don't understand how dictionaries work, I'd recommend simplifying the problem. Create one array for each section, then inside your delegate methods use a switch() statement to call [array count] for the row count etc. For the section count you could still use the original dictionary with [[dictionary allKeys] count].
EDIT:
I just saw #fzwo recommends the same thing in two comments
Your best bet is an array of arrays, as has been mentioned. To avoid the complexity with dictionaries, create two NSArray ivars for the table data and the section titles.
// in viewDidLoad
tableData = [NSArray arrayWithObjects:
[NSArray arrayWithObjects:
#"Row one title",
#"Row two title",
nil],
[NSArray arrayWithObjects:
#"Row one title",
#"Row two title",
#"Row three title",
nil],
nil];
sectionTitles = [NSArray arrayWithObjects:
#"Section one title",
#"Section two title",
nil];
// in numberOfSections:
return tableData.count;
// in numberOfRowsInSection:
return [[tableData objectAtIndex:section] count];
// in titleForHeaderInSection:
return [sectionTitles objectAtIndex:section];
// in cellForRowAtIndexPath:
...
cell.textLabel.text = [[tableData objectAtIndex:indexPath.section]
objectAtIndex:indexPath.row];
You could use other objects instead of the row titles if you need more data available to your cell.
To get the number of rows in your section you can use the following:
tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *key = [[dictionary allKeys] objectAtIndex: section];
return [[dictionary objectForKey:key] count];
}
And to get the cell value:
tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *key = [[dictionary allKeys] objectAtIndex: indexPath.section];
NSArray *values = [dictionary objectForKey:key];
NSString *value = [values objectAtIndex: indexPath.row];
// code to create a cell
return cell;
}
So I have a UITableView, and I populate the tableview with data from a .plist. This has been working fine for me until today, when I tried to do the same and I can't get the numberOfRowsInSection, method to work. Here is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if...
else if (segmentOptions == exchange){
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
return [array count];
}
//Else
return contentArray.count;
}
So in that code, everytime I run it, the code crashs. But, I use basiacally the same code to set the tableview text and that works fine:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if...
else if (segmentOptions == exchange) {
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:indexPath.section]]];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
}
return cell;
}
And that code works fine, which is why I'm so confused. When I set the number of rows to return to a specific number, and run the rest of the code, everything works fine. So I'm really lost. Thands in advance
UPDATE
I tried it with the proper count notation, return [array count];, and I still get the same crash and the same console output.
First, count is not a property so you should not be using dot syntax to access it.
I would suggest changing your code so that you are not accessing the count method like a property.
Second,
Test to see if your array is nil and that it is even an array.
Third,
Post the actual complete stack trace.
Break it down and debug, if console message is not being helpful. It helps sometimes, specially when it's late. i.e.
// NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
NSLog(#"%d", section);
id objAtIndex = [listOfExchanges objectAtIndex:section];
NSLog(#"%#", listOfExchanges);
NSLog(#"%#", objAtIndex);
id objForKey = [exchangeDictionary objectForKey:objAtIndex];
NSLog(#"%#", exchangeDictionary);
NSLog(#"%#", objForKey);
Try this:
[array count]
count is not a property, it is a method you run on the array.
So I have an NSDictionary with 4 objects in it. Each of these objects then has 2 properties, name and date
I can list out all the data by logging it.
I am assuming your sample code is inside of this method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
If not, that is your first problem.
Right now, you are probably sequentially setting each cell to have every title one by one, until it gets to the end of the list. All of the cells have the same title because they all have the last title in the list.
You should drop the for-loop and use this instead:
NSDictionary *object = [objects objectAtIndex:[indexPath row]];
NSString *title = [object objectForKey:#"title"];
NSString *date = [object objectForKey:#"publishedDate"];
cell.textLabel.text = title;
cell.detailTextLabel.text = date;
i am using a function to fill dictionary in a array
here is the code
-(void)getAllFlashCardsNames
{
if ([listofitems count]==0)
listofitems = [[NSMutableArray alloc] init];
else
[listofitems removeAllObjects];
for(int i=0;i<listOfCategoryId.count;i++)
{
int j=[[listOfCategoryId objectAtIndex:i]intValue];
[self getFlashCard:j];
NSArray *flashCardsNames = flashCardsNamesList;
NSArray *flashCardsids = flashCardsId;
NSLog(#"FLash Card Ids %#",flashCardsids);
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:flashCardsNames,#"flashCards",flashCardsids,#"flashCardId",nil];
[listofitems addObject:dictionary];
}
}
in the above code the array flashcardsNamesList,flashCardsId changes everytime when calling the function [self getFlashCard:j]; j is a parameter to change categoryid which comes from the listOfCategoryId array..
now how do i retrieve values from the dictionary i want to show different flashcardsNames on different sections in uitableview.
here is the code i m using to retrieve values
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [listofitems count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
NSDictionary *dictionary =[listofitems objectAtIndex:section];
NSLog(#"dictionary=%#",dictionary);
NSArray *array =[dictionary objectForKey:#"flashCards"];
NSLog(#"array=%#",array);
NSLog(#"Section Count = %d",array.count);
return array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableViewdequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dictionary =[listofitems objectAtIndex:indexPath.section];
NSArray *array =[dictionary objectForKey:#"flashCards"];
NSArray *array1=[dictionary objectForKey:#"flashCardId"];
NSString *cellValue=[array objectAtIndex:indexPath.row];
NSString *cellValue1=[array1 objectAtIndex:indexPath.row];
[cell.FlashCardsNames setText:cellValue];
[cell setFlashCardId:[cellValue1 intValue]];
return cell;
}
but the method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath does not get called
but the method -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath does not called
Have you set the object that your method is implemented in as the data source of your table view? UITableView hands some of the work off to another object, which must conform to the UITableViewDataSource and UITableViewDelegate protocols; you must then set the object as the dataSource and delegate of the table view, either in IB or programmatically (the data source and delegate can be different objects, but are commonly the same object). Take a look at this article which explains more about it; once this has been done, your object must handle the tableView:cellForRowAtIndexPath: and tableView:numberOfRowsInSection: methods, which will be called on your object by the table view.
Also, the lines:
if ([listofitems count]==0)
listofitems = [[NSMutableArray alloc] init];
do not make sense. I assume you are checking whether the array has been allocated or not, and if not, to allocate it. If the array hasn't been allocated, it will be nil, so sending count to it will have no effect anyway. If it has been allocated previously, but deallocated but not reverted back to nil it will be a bad pointer and cause your application to crash.
A better way to allocate it would be to do so in your class's awakeFromNib method, or applicationDidFinishLaunching: method, if you are implementing this in your UIApplicationDelegate subclass. Don't forget to release it in your dealloc method.