please suggest me how to display data like tree view.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return marrSearchResult.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
int iCount=0;
if (section==0) {
iCount =(int)[marrSearchResult count];
}else if(section==1){
iCount =(int)[[[[marrSearchResult objectAtIndex:section] valueForKey:#"data"] valueForKey:#"result"] count]+1;
}else{
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"MyTravelProfileTblCELL";
if (indexPath.section == 0) {
}else{
}
}
see below image desplay like this
Follow these steps :
Create custom tableview cell for section header (Tourist attractions, Government/Community). Lets call it PlaceTypeCell
Create another custom tableview cell for rows (Museums, Hospitals... ). Lets call it PlaceNameCell.
Return the section count as the count of main array (you already did it)
Return the row count as the count of subarray at the index of section in the main array (also you did it)
Now in the cellForRowAtIndexPath, get the sub array from main based on section number (indexPath.section). Now get the required row item(Place name and details) from sub array using row number (indexPath.row). Using the data in that row item populate the table cell.
Now in the viewForHeaderInSection get the place type details from the main array using section number and populate the PlaceTypeCell and return as section header. Have a look at Best way to create custom UITableview section header in storyboard
Set the height for section header using heightForHeaderInSection
Hope it helps.
Edit : If you can show the format of marrSearchResult, then it will be easy to help.
Create Input array in Format:
NSArray *tourismSection = #[#"Museums", #"Aquariums"];
NSArray *govSection = #[#"Hopsital"];
NSDictionary *data = #{
#"tourism" : tourismSection,
#"gov" : govSection
};
NSArray *inputs = #[#"tourism",#"gov" ];
in numberOfSectionsInTableView
return inputs.count;
in numberOfRowsInSection:
return [data valueForKey:inputs[indexPath.section]].count;
Related
I am trying to implement accordion tableview with parent and child custom tableview cells. I am using below mentioned open source code.
Source code : https://github.com/singhson/Expandable-Collapsable-TableView
In that code having single tableview with single tableview cell. It will show for parent and child cells but I want to make:
Main storyboard Tableview
Parenttableviewcell separate class and xib
Childtableviewcell separate class and xib
It should apply on main controller tableview with accordion. Right now in this code there is no separate custom cells (parent and child using same tableview cell and changing data only).
You can implement it by trying to manage the sections and rows of a table view, thats what i assume to be the simplest way to implement it without using any third party code. For example
All the section headers will contain their own number of rows.
Take a array or dictionary or array that will store the state of expanded rows in sections. (Say '1' for expanded state and '0; for collapsed state)
If in the initial state, all the UI is expanded then set all the objects '1' in array or dictionary.
On tap of individual headers (I am assuming section will be collapsed on click on individual header of section) you can get which section need to be collapsed. Retain this state as '0' for collapsed section rows in the array or dictionary.
Reload the table and check in heightForRow delegate method for the '0' entity in your array or dictionary. Wherever you find it to be '0', return height as 0 in the delegate method.
Perform the opposite for reverse functionality.
UPDATE FOR CODE
- (IBAction)btnMenuViewTypeTapped:(id)sender{
UIButton *btnSender = (UIButton *)sender;
if(menuViewType == MVTCollapse){
[btnSender setImage:[UIImage imageNamed:#"MenuCollapse"] forState:UIControlStateNormal];
menuViewType = MVTExpand;
for(NSInteger intAtIndex=0; intAtIndex<[mutArrSearchMenuItems count]; intAtIndex++){
[mutArrSectionOpened replaceObjectAtIndex:intAtIndex withObject:#"1"];
}
} else{
[btnSender setImage:[UIImage imageNamed:#"MenuExpand"] forState:UIControlStateNormal];
menuViewType = MVTCollapse;
for(NSInteger intAtIndex=0; intAtIndex<[mutArrSearchMenuItems count]; intAtIndex++){
[mutArrSectionOpened replaceObjectAtIndex:intAtIndex withObject:#"0"];
}
}
[tblViewRestaurantMenu reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [mutArrSearchMenuItems count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSInteger intNumOfRow;
if([mutArrSectionOpened[section] isEqualToString:#"1"]){
intNumOfRow = [mutArrSearchMenuItems[section][strMenuType] count];
}
else{
intNumOfRow = 0;
}
return intNumOfRow;
}
You can implement it by using SKSTableview.
for that Please refer the below link:
SKSTableView
Let make two kinds of custom cell.
+Parent cell is tableview sectionHeader
+Child cell is normal cell
/*your datasource like this
arrData = #[section, section, section ....]
section.name
section.image
section.arrayChild
arrayChild = #[child, child, child....]
child.name
child.image
*/
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return arrData.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
section = arrData[section];
child = section.child;
return child.count;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
//Cell is Custom of UITableViewHeaderFooterViewCell
//load your Parent Cell here
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//load your custom chill cell here
}
I have a tableViewController, and under that i want one static cell and rest of all will be dynamic cells . I have already run for dynamic cells , but within same tableViewController i also need to add one static cell, how can i achieve it?
Please Help
Thanks in advance.
you could do something like the following:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dynamicContent.count + 1; // +1 for the static cell at the beginning
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
// static cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"StaticCellIdentifier" forIndexPath:indexPath];
// customization
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DynamicCellIdentifier" forIndexPath:indexPath];
id contentObject = self.dynamicContent[indexPath.row];
// customization
return cell;
}
You cannot create static and dynamic cell at same time in a UITableViewController.
But you can hard code your static cell's data and load the data each time you reload your tableview.
You can keep all your cells in one section and keep checking for index path.row == 0 or create separate sections for them.
typedef NS_ENUM(NSUInteger, TableViewSectionType) {
TableViewSectionType_Static,
TableViewSectionType_Dynamic
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2; // One for static cell, and another for dynamic cells
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
switch(section) {
case TableViewSectionType_Static:
return 1; // Always return '1' to show the static cell at all times.
case TableViewSectionType_Dynamic:
return [myDynamicData count];
}
}
With this approach your cells will be split into two sections and it will be easier to manage. And it will always show one cell, as number of rows returned for TableViewSectionType_Static is 1 always. It will show the dynamic cells based on your data count.
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.
I have app in which I want to show the data in table view sections problem is that I do not know the total sections names as it depends on array. So how to show data for each section in cell for row at index path.
NSArray *test=[NSArray arrayWithObjects:#"June 20",#"July 20","May 1",#"May 10",nil];
So I want to show the data in the tableView sections date wise like if June 20 all the records of June 20 should be shown in one sections and in May 1 all the records for May same goes for all. Any idea how to solve this. Thanks
It's best to create a standard structure like (personally, i'd suggest the following):
Array that contains multiple dictionaries
Each dictionary contains 2 keys
Day is a key and, say, June 20, is it's value
Events is a key and, it's value is an array object
This array is a collection of strings that will basically be the content for these days
Example:
Possible UITableViewController subclass methods
- (void)viewDidLoad
{
[super viewDidLoad];
arrTest = #[
#{#"Day":#"June 20",
#"Events":#[#"Repair window pane", #"Buy food for Elephant", #"Pay credit card dues"]},
#{#"Day":#"July 20",
#"Events":#[#"Repair window frame", #"Buy alot more food for Elephant", #"Pay credit card dues dues"]},
#{#"Day":#"May 1",
#"Events":#[#"Replace entire window", #"Sell Elephant, Get Cat", #"Return credit card"]},
#{#"Day":#"May 10",
#"Events":#[#"Take bath", #"Shave", #"Get new credit card"]}
];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//get count of main array (basically how many days)
return arrTest.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//get count of number of events in a particular day
//old style
//return [[[arrTest objectAtIndex:section] objectForKey:#"Events"] count];
return [arrTest[section][#"Events"] count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
//get value of the "Day" key (June 20 / July 20 ...)
//old style
//return [[arrTest objectAtIndex:section] objectForKey:#"Day"];
return arrTest[section][#"Day"];
}
- (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];
}
//old style
//NSString *strDayEvent = [[[arrTest objectAtIndex:indexPath.section] objectForKey:#"Events"] objectAtIndex:indexPath.row];
NSString *strDayEvent = arrTest[indexPath.section][#"Events"][indexPath.row];
[cell.textLabel setText:strDayEvent];
return cell;
}
To decide number of section and header title for particular section you need to do implement UITableView delegates methods.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [test count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [test objectAtIndex:section];
}
The section name and the row contents have a relationship...and therefore the most suitable way is to manage it with objects displaying relationship like the requirement
For your case an object/structured array will do the job for you with object has a string content to store the date text and the array storing the cell content data
Or use an NSDictionary with key as date and value as the cell content data as array
I am new to ios programming so bear with me if the question is simple. I have a core data table mapped to a table view controller. The data in it currently looks as follows - there is one prototype cell:
I need to sum up the data by dates and show the details of each date in a different section with the summed up total coming up as the first row. Something like:
My question is is this doable? I am thinking I need to create sections and two prototype cells within each table cell. Would appreciate quick feedback.
Thanks all!
The easy way to do this is using section headers. You can either use a single string (#"%#: %#", date, total) or a wrapper view with a label on the left for the date and on the right for the total.
-(NSString *) tableView:(UITableView *)tv titleForHeaderInSection:(NSInteger)s
{
NSString *dateString = [self dateStringForSection:s];
float total = [self totalForSection:s];
return [NSString stringWithFormat:#"%#: %0.2f", dateString, total];
}
Or
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return [self wrappedHeaderForSection:s];
}
You'll have to implement dateStringForSection: or wrappedHeaderForSection: appropriately, of course.
The easiest way is to style your UITableView to 'UITableViewStyleGrouped'.
UITableView *tab = [[UITableView alloc] initWithFrame:rect style:UITableViewStyleGrouped];
Or you can go to interface builder and in Table View change style from plain to grouped.
The style 'Grouped' divides your table into multiple sections.
The using UITableViewDelegate methods specify all the parameters.
// Tell the number of section in table
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return numberOfSections;
}
//Tell the number of rows in each section
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
{
return 2;
} else if(section == 1)...
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 0)
{
//Show Amount for Jul 02, 2013
cell.textLabel.text = #"Jul 02, 2013";
cell.detailTextLabel = #"20.35";
}
// Do the same for all rows and section in table.
}
For further reference -
http://mobisoftinfotech.com/iphone-uitableview-tutorial-grouped-table/
You should also definitely check out the Sensible TableView framework. Saves me tons of time when working with Core Data.