number of rows in section - ios

I have a table view which populates from a plist. in a plist I have a Categories array:
Catgeories - Array
item 0 - Maths
item 1 - English
....
in the same plist i have a Notes array
Notes - Array
item 0 - Dictionary
Title - My maths note 1
Text - This is algebra
Category - Maths
item 1 - Dictionary
Title - My English
Text - This is algebra
Category - English
in number of sections i have...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [self.categories count];
}
In numberOfRowsInSection before i added the categories array to the plist i could simply use
return self.notes.count;
which produces a duplicate in every category: http://i.stack.imgur.com/9xScH.png
but now in this method i should expect to return the number of rows based on the section, not sure how to do this

You need to do something like that:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
return self.notes.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.notes[section].count;
}
You get array of you notes base on the section and return count of the array.
//EXTENDED
If you want to have as many section as data in Category array use:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
return self.catgeories.count;
}
The self.note array contain dictionaries object with Category key and I believe you want to show all of the data for section where category is equal section category. To do that you have to filter your notes array, try this (I assume that you have distinct objects in Caregory plist):
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Get category
NSString *cat = self.catgeories[section];
//Filter notes array
NSPredicate *pred = [NSPredicate predicateWithFormat:#"Category =[cd] %#", cat];
NSArray * catArray = [self.notes filteredArrayUsingPredicate:pred];
return catArray.count;
}

I have edited the answer.
If you wanna access large amount of data, i suggest that you store your data in core data instead of plist,
For getting number of rows for each section you can use this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// check if the count of the array is greater than number of sections
if (self.notes.count > section)
return [[[self.notes objectAtIndex:section]allObjects]count];
}
Hope it helps :)

You can try like this if you want to return different number of rows in each section:-
- (NSInteger)tableView:(UITableView
*)tableView numberOfRowsInSection:
(NSInteger)section
{
int rows=0;
if(section==0)
{
rows=1;
}
if(section==1)
{
rows=2;
}
rerurn rows;
}

Related

Multiple UITableViewController and one model class to hold data

I'm having trouble deciding.
I created a model class, and another one as a singleton,
the singleton uses a NSMutableArray and returns a NSArray as a copy.
One of the UITableViewController will show the array of data.
The question is, if I want to show different data on each UITableViewController should i create multiple arrays and methods that save and edit the arrays or is there a better way to do this?
On your UITableViewDataSource methods, you can decide what information to return based on which TableView is calling the method. For example:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//Check which tableview is calling
if (tableview == self.tableView1) {
// Return the number of sections for each possible Table
return 1;
} else {
return 2;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
// If you're serving data from an array, return the length of the array:
if (tableview == self.tableView1) {
// Return the number of sections for each possible Table
return [dataArray1 count];
} else {
return [dataArray2 count];
}
}
And the same for any DataSource/Delegate methods you may need to implement.
Hope that helps!!

Blank rows on 2 TableViewController with data from one Viewcontroller in the other viewcontroller

I have 2 UITableViewControllers in my project.
The problem I am having is that I am getting blank cell entries in the tableView opposite to the tableView where the data is entered.
I can't seem to figure out why this is the case.
It's creating blank rows in this tableView even though the information is from the other UITableViewController.
Here's the main tableView part from the one of the 2 UITableViewControllers:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"number of addedSpaceObjects %lu",(unsigned long)[self.diaryoptions count]);
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"number of sections %ld",(long)section);
// Return the number of rows in the section.
return [self.diaryoptions count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentification = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentification
forIndexPath:indexPath];
Data2 *diary = [self.diaryoptions objectAtIndex:indexPath.row];
cell.textLabel.text = diary.diaryname;
cell.detailTextLabel.text = diary.diaryWeight;
return cell;
}
And from other UITableViewController:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"number of addedSpaceObjects %lu",(unsigned long)[self.addedSpaceObjects count]);
// Return the number of sections.
if ([self.addedSpaceObjects count]) {
return 2;
}
else {
return 1;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"number of sections %ld",(long)section);
// Return the number of rows in the section.
if (section == 1) {
return [self.addedSpaceObjects count];
}
else {
return [self.recipes count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentification = #"Josh";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentification
forIndexPath:indexPath];
if (indexPath.section == 1) {
Data *recipe = [self.addedSpaceObjects objectAtIndex:indexPath.row];
cell.textLabel.text = recipe.name;
}
else {
// Configure the cell...
Data *recipe = [self.recipes objectAtIndex:indexPath.row];
cell.textLabel.text = recipe.name;
}
return cell;
}
Here is the full project on GitHub. https://github.com/josher32/Plant-Diet
Appreciate any help anyone can offer!
Ok, so I checked out the app and I'll try my best to explain the problem as precisely as I can to cover it adequately.
Firstly, the classes in question are:
RecipesTableTableViewController
AddRecipeViewController
Data
DiaryTableViewController
AddDiaryViewController
Data2
Secondly, we'll need to look into your
#define ADDED_SPACE_OBJECTS2 #"Added Space Objects Array"
AddRecipeViewController
So... AddRecipeViewController basically creates a Data object that is kept in an array and eventually stored in NSUserDefaults under the key name Added Space Objects Array.
Great!! So you now have got recipe related stuff in some Data object.
AddDiaryViewController
Same thing here.
AddDiaryViewController creates a Data2 object that is eventually stored in NSUserDefaults under the same key name Added Space Objects Array.
But before storing this, you're taking the old value of the key Added Space Objects Array, which is an array, and adding a new object to it before placing it back into NSUserDefaults.
But now... this array will now have a combination of Data as well as Data2 objects!
RecipesTableTableViewController
When we come here, things get real.
- (void)viewDidLoad
{
//...
NSArray *myRecipeAsPropertyLists = [[NSUserDefaults standardUserDefaults] arrayForKey:ADDED_SPACE_OBJECTS_KEY];
for (NSDictionary *dictionary in myRecipeAsPropertyLists) {
Data *spaceObject = [self spaceObjectForDictionary:dictionary];
[self.addedSpaceObjects addObject:spaceObject];
}
}
Since we already realized that self.addedSpaceObjects can contain Data as well as Data2 objects, in the case whendictionary is containing stuff specific to type Data2, spaceObjectForDictionary will not be able to translate it properly to the required Data object.
We're expecting name, title, ingredients, directions but we're getting diaryentry, diaryname,diaryWeight.
So (in this scenario):
The values of name, title, ingredients, directions will be nil
The section-row count will be incorrect because it will give count of both Data as well as Data2 objects (and we don't care about Data2 objects in the RecipesTableTableViewController class... right?... well anyways, I assumed)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
if (indexPath.section == 1) {
Data *recipe = [self.addedSpaceObjects objectAtIndex:indexPath.row];
cell.textLabel.text = recipe.name;
}
//...
}
We see recipe.name is nil, for some indexPaths, ergo blank rows and vice versa in DiaryTableViewController.
Solution:
Firstly, I wouldn't recommend NSUserDefaults for your purposes but anyways...
Basically, don't use a single #"Added Space Objects Array" key for your NSUserDefaults stuff.
I'd suggest you use 2 separate keys.
//replace
//#define ADDED_SPACE_OBJECTS2 #"Added Space Objects Array"
//with
#define ADDED_SPACE_OBJECTS2 #"RecipeEntries" //in RecipesTableTableViewController
//and
#define ADDED_SPACE_OBJECTS2 #"DiaryEntries" //in DiaryTableViewController
Basically, segregate the entries instead of mixing them up under a single key name.
This seems like the quickest way to solve your problem without changing your logic.

Scrolling with indexbar in a tableview

I got a table view with approx 45k items. I want to use the indexbar to be able to scroll faster through my list.
Now I've looked at other questions on here, but I just can't figure out what to do.
I've got the following two functions:
-(NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return alphabetsArray;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return index;
}
I don't understand what I should do next. Like, I have an array called airports which is sorted alphabetically. What should I be doing with this array?
update
so I found an article I could use and I'm pretty close now, I think. My table view only shows 2 items now though.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"ROWS METHOD CALLED");
NSArray *unsortedKeys = [alphabetizedAirports allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:section];
NSArray *airportsForSection = [alphabetizedAirports objectForKey:key];
return [airportsForSection count];
}
I have about 60 items in my sortedKeys array. The airportsForSection array only gets 2 items though so when it returns the array, the tableview only shows 2 items. Any ideas how to solve?

sectionForSectionIndexTitle in UITableView iOS

I have just started in ios, and I am stuck with UITableView.
I want to implement index bar in right side of the view. I have implemented this but when I tap on the section on the index bar it's not working.
This is my code. Here indexArray is as "A-Z" element and finalArray is my UITableView mutable array.
Please tell me what should i implement in sectionForSectionIndexTitle.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [finalArray count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section
{
return [finalArray objectAtIndex:section];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return indexArray;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle: (NSString *)title atIndex:(NSInteger)index
{
}
This is perhaps one of the most confusing methods in the UITableViewDataSource, its best to consider an example:
Lets say you have a table view with 4 items:
section index - 0 section title - 'A'
items: ['Apple', 'Ant']
section index - 1 section title - 'C'
items: ['Car', 'Cat']
You then have 26 section index titles (the index on the right side of the table view): A - Z
Now the user taps on letter 'C' you get a call to
tableView:sectionForSectionIndexTitle:#"C" atIndex:2
You need to return 1 - the section index for the 'C' section.
If the user taps 'Z' you will also have to return 1 since you only have 2 sections and C is the closest to Z.
In the simple case where you have the same sections in your table view as the index on the right had side its ok to do this:
- (NSInteger)tableView:(UITableView *)tableView
sectionForSectionIndexTitle:(NSString *)title
atIndex:(NSInteger)index
{
return index;
}
Otherwise it depends on your setup. You might have to look for the title in you section titles:
NSInteger section = [_sectionTitles indexOfObject:title];
if (section == NSNotFound) // Handle missing section (e.g. return the nearest section to it?)

How to dynamically define different no of rows for different no of sections in a UITableView?

I have a tableview where i return the no of sections and no of rows for each sections dynamically. I can implement it like this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if( section == 0)
return [array count];
if( section == 1)
return [array2 count];
if( section == 2)
return [array3 count];
}
if i am aware that i have 3 sections i can do it in this above mentioned way. But how to dynamically define the no of rows for different sections. e.g:- u have if(section == 0). i dont want to hard code the value of 0,1,2 here. I am not sure about the total no of sections. How can we do it we want to return the no of rows dynamically for different sections? I have an array to display no of sections and different arrays to display no of rows for each section. How to dynamically mention in the method "numberOfRowsInSection"?
here you can follow this approach , you can put all your countable arrays in another NSMutableArray like lets say tmpArray (e.g. tmpArray[0] = array or tmpArray[1] = array2 , or just by appending [tmpArray addObject:array] ..),
then you can go like this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[tmpArray objectAtIndex:section] count];
}
i hope this will help you to solve your problem ..

Resources