iOS: How can i display the section content in Grouped Table View? - ios

I am using the following sample code to have the section contents in "Grouped Table View". Showing the contents in "Grouped Table View" is fine.
But, the issue is, it sorts the section content based on alphabetical order, so the order of section header content is not displaying as expected. For example: I want "About" to be shown at the end of section in tableview, but here it is always shows first (because of alphabetical sort does there). How can i display the section content based on the below code without alphabetical sorting. Please advise!
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *arrTemp4 = [[NSArray alloc]initWithObjects:#"Quick Logon",#"Stay Logged On", nil];
NSArray *arrTemp3 = [[NSArray alloc]initWithObjects:#"Notifications",#"Text Messaging",#"Family Members",#"Social Media",nil];
NSArray *arrTemp2 = [[NSArray alloc]initWithObjects:#"Payment Accounts",nil];
NSArray *arrTemp1 = [[NSArray alloc]initWithObjects:#"Phone Nickname",#"Version",nil];
NSDictionary *temp = [[NSDictionary alloc]initWithObjectsAndKeys: arrTemp1,#"About", arrTemp2,#"Payment Preferences", arrTemp3,#"Profile & Preferences", arrTemp4,#"Security ", nil];
self.tableContents = temp;
NSLog(#"table %#",self.tableContents);
NSLog(#"table with Keys %#",[self.tableContents allKeys]);
self.sortedKeys = [[self.tableContents allKeys] sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"sorted %#",self.sortedKeys);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [self.sortedKeys count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.sortedKeys objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
NSArray *listData =[self.tableContents objectForKey:[self.sortedKeys objectAtIndex:section]];
return [listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self.tableContents objectForKey:[self.sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.accessoryType = indexPath.section > 0 ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
NSLog(#"indexPath.section %d",indexPath.section);
if ( indexPath.section==0 )
{
// cell.imageView.image = [UIImage imageNamed:#"icon.png"];
}
//cell.switch.hidden = indexPath.section > 0;
return cell;
}
Thanks in Advance!

Don't use sortedArrayUsingSelector:. Instead, explicitly create the key array in the order that you want. Then, create tableContents using that key array and another array created to hold all of your content arrays (using dictionaryWithObjects:forKeys:).
NSArray *keys = #[ #"About", #"Payment Preferences", #"Profile & Preferences", #"Security" ];
NSArray *values = #[ arrTemp1, arrTemp2, arrTemp3, arrTemp4 ];
self.tableContents = [NSDictionary dictionaryWithObjects:values forKeys:keys];
self.sortedKeys = keys;

Related

I am trying to display detail list of may json response in UITableViewcell

Hi I am trying to display detail information of json data in second table view but their is some mistake in my logic so please help me my json response is in image and I am trying to to dispaly channel response in table view when user click the same cat_id then display all related channel list and image in second tableViewcell please help me..
-(void)getCategories
{
Service *srv=[[Service alloc]init];
NSString *str=#"http://streamtvbox.com/site/api/matrix/";//?country_code=91&phone=9173140993&fingerprint=2222222222";
NSString *method=#"channels";
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
[srv postToURL:str withMethod:method andParams:dict completion:^(BOOL success, NSDictionary *responseObj)
{
NSDictionary *dict = [[NSDictionary alloc]initWithDictionary:[responseObj valueForKey:#"categories"]];
arrayChannelList=[responseObj valueForKey:#"channels"];
NSLog(#"Array : %#",channels);
for (NSDictionary *dict in arrayChannelList)
{
//NSArray *tempTitle = [[NSArray alloc]init];
arrayCat_Id = [dict objectForKey:#"cat_id"];
}
tempArray = [[NSArray alloc]init];
tempArray = [dict allKeys];
for(int i=0; i<tempArray.count; i++)
{
[arrayCategories addObject:[dict valueForKey:[tempArray objectAtIndex:i]]];
}
NSLog(#"%#",arrayCategories);
[tblView reloadData];
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"%lu",(unsigned long)[arrayCategories count]);
return arrayCategories.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ChannelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [arrayCategories objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
DetailChannelsViewController *detailVC = (DetailChannelsViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"DetailView"];
detailVC.channelTitle = [arrayCategories objectAtIndex:indexPath.row];
detailVC.SubChannelName = arrayCat_Id;
NSLog(#"%#",arrayCat_Id);
[self.navigationController pushViewController:detailVC animated:YES];
}
Just initialize of your NSmutuableArray and add the value of with addobject like:-
arrayCat_Id=[[NSMutableArray alloc]init];
for(your logic){
[arrayCat_Id addobject:[dict objectForKey:#"cat_id"];
}

How to show Data in UITableView ios

Developing a iPAD app, where I'm trying to populate table, This is how i'm doing:
In view did load, I'm creating two dictionary object and adding object as Pdf and Excel.
- (void)viewDidLoad
{
[super viewDidLoad];
arrDocuments = [[NSMutableArray alloc] init];
NSArray *arr1 = [NSArray arrayWithObjects:#"PDF", nil];
NSDictionary *pdf = [NSDictionary dictionaryWithObjects:arr1 forKeys:nil];
NSArray *arr2 = [NSArray arrayWithObjects:#"Excel", nil];
NSDictionary *excel = [NSDictionary dictionaryWithObjects:arr2 forKeys:nil];
[arrDocuments addObject:pdf];
[arrDocuments addObject:excel];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrDocuments count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
//return [arrReceipes count];
NSDictionary *dictionary = [arrDocuments objectAtIndex:section];
NSArray *array = [dictionary objectForKey:[self.sortedKeys objectAtIndex:section]];
return [array count];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableView *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell ==nil) {
cell = [[UITableViewCell alloc]initWithFrame:CGRectZero reuseIdentifier:MyIdentifier];
}
return cell;
}
With this implementation I'm not able to see table view.Its going to main method and showing me SIGABRT message.Where I'm going wrong??
While creating NSDictionary, you have passed nil in place of keys array,
NSDictionary *pdf = [NSDictionary dictionaryWithObjects:arr1 forKeys:nil];
You should give proper objects and keys to the dictionary. This method expects objects and keys to be given in an array as you can see in its method signature.
+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys

How to set titleForHeaderInSection manually

I load data from plist to uitableview like this:
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:#"data.plist"];
NSMutableDictionary *resultDic = [[NSMutableDictionary alloc] init];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSDictionary *myDict = [NSDictionary dictionaryWithContentsOfFile:path];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"purpleKey"])
{
NSArray *purple = [myDict objectForKey:#"Purple"];
[resultArray addObject:#"Purple"];
[resultDic setValue:purple forKey:#"Purple"];
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"orangeKey"])
{
NSArray *orange = [myDict objectForKey:#"Orange"];
[resultArray addObject:#"Orange"];
[resultDic setValue:orange forKey:#"Orange"];
}
self.tableData = resultDic;
self.sectionsTitle = resultArray;
}
titleForHeaderInSection
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionsTitle objectAtIndex:section];
}
my plist structure
My question is:
How can I manually set title for Purple header and Orange header without to changing names in plist file?
like this: Purple = Category 1, Orange = Category 2
EDIT
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sectionsTitle.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionsTitle objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int num = [[tableData objectForKey:[sectionsTitle objectAtIndex:section]] count];
if (num > 3) {
num = 3;
}
return num;
}
// 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];
}
NSDictionary *dict = [[tableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.numberOfLines = 1;
cell.textLabel.font = [UIFont systemFontOfSize:11];
cell.textLabel.text = [NSString stringWithFormat:#"%# - %#", [dict objectForKey:#"Name"], [dict objectForKey:#"Address"]];
if ([dict objectForKey:#"Address"] == (NULL)) {
//do nothing
}
return cell;
}
From the look of your code, the section headers are coming from resultsArray, which you are populating with the constant strings Orange and Purple.
You can just put different constant strings into that array, unless I'm missing something.
So, instead of
[resultArray addObject:#"Orange"];
Use
[resultArray addObject:#"Category 1"];

Different section headers in UITableView of a nested NSArray

I am trying to learn how to code a UITableView and is having some problems with the programming of the section.
I have declared 3 arrays with strings and 1 array with the 3 arrays.
firstSection = [NSArray arrayWithObjects:#"Red", #"Blue", nil];
secondSection = [NSArray arrayWithObjects:#"Orange", #"Green", #"Purple", nil];
thirdSection = [NSArray arrayWithObject:#"Yellow"];
array = [[NSMutableArray alloc] initWithObjects:firstSection, secondSection, thirdSection, nil];
To shows the headers
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
NSString * title;
title = [NSString stringWithFormat:#"%#" , [array objectAtIndex:section]];
return title;
}
which shows the array itself as the headers
therefore is it possible to actually show the name of the sections using the names of the arrays such as firstSection and secondSection?
In your case, it's better to store your arrays in an NSDictionary. For example, if you declare and synthesize an NSDictionary variable called tableContents and an NSArray called titleOfSections, you can do something like this:
- (void)viewDidLoad {
[super viewDidLoad];
//These will automatically be released. You won't be needing them anymore (You'll be accessing your data through the NSDictionary variable)
NSArray *firstSection = [NSArray arrayWithObjects:#"Red", #"Blue", nil];
NSArray *secondSection = [NSArray arrayWithObjects:#"Orange", #"Green", #"Purple", nil];
NSArray *thirdSection = [NSArray arrayWithObject:#"Yellow"];
//These are the names that will appear in the section header
self.titleOfSections = [NSArray arrayWithObjects:#"Name of your first section",#"Name of your second section",#"Name of your third section", nil];
NSDictionary *temporaryDictionary = [[NSDictionary alloc]initWithObjectsAndKeys:firstSection,#"0",secondSection,#"1",thirdSection,#"2",nil];
self.tableContents = temporaryDictionary;
[temporaryDictionary release];
}
Then in the table view controller methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [self.titleOfSections count];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
return [[self.tableContents objectForKey:[NSString stringWithFormat:#"%d",section]] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
//Setting the name of your section
return [self.titleOfSections objectAtIndex:section];
}
Then to access the contents of each array in your cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *arrayForCurrentSection = [self.tableContents objectForKey:[NSString stringWithFormat:#"%d",indexPath.section]];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
cell.textLabel.text = [arrayForCurrentSection objectAtIndex:indexPath.row];
return cell;
}
can u do like this
NSArray *SectionArray = [[NSArray alloc]initwithArray:[array objectAtIndex:section]];
NSString * title;
title = [NSString stringWithFormat:#"%#" , [SectionArray objectAtIndex:section]];
return title;

How to modify iPhone plist to add another level and access data in code

I have a plist with an alphabetical indexed list of entries. I now want to add a further level so that each entry has a definition text (like a small dictionary.) I need some advice as to how to modify my plist and code to accommodate this. The existing code is below - it's from the Apress book, but I can't seem to modify it for another level.
NSString *path = [[NSBundle mainBundle] pathForResource:#"sortedglossary" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc]initWithContentsOfFile:path];
self.names = dict;
[dict release];
NSArray *array = [[names allKeys] sortedArrayUsingSelector:#selector(compare:)];
self.keys = array;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(#"numberOfSectionInTable start");
return [keys count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"numberOfRowsInSection start");
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];
return [nameSection count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SectionsTableIdentifier] autorelease];
}
cell.text = [nameSection objectAtIndex:row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSLog(#"titleForHeader");
NSString *key = [keys objectAtIndex:section];
return key;
}
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return keys;
}
There are a number of ways to accomplish this. Normally I will just create another child of the root node in the plist for definitions.
So your plist would have the array of your entries and it would have another dictionary. The dictionary contains the definition text, keyed by the values from the first array. That way, you can just look up the definition when you need it.
So the structure would look roughly like this:
Root
Entries(NSArray)
0 => entryA(NSString)
1 => entryB(NSString)
...
x => entryX(NSString)
Definitions(NSDictionary)
entryA(NSString) => definitionA(NSString)
entryB(NSString) => definitionB(NSString)
...
entryX(NSString) => definitionX(NSString)

Resources