Section Header Titles incorrect - ios

I have been trying to set the uiTableViewHeader for my UITableView for a couple of days now with no luck. I don't think I am far off. Currently it shows the section Titles however multiples the number of records by X amount ( I presume my count may be wrong).
I think I need to further configure my cellForRowAtIndexPath method but Im unsure how.
I am a bit confused. I need to group the rowsAtIndexPath to the sections and stop them multiplying.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"atozCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
//Searchbar code is here
NSDictionary *dataDict = [self.sortedArray objectAtIndex:indexPath.section];
cell.textLabel.text = [dataDict objectForKey:#"Title"];
}
return cell;
}
Section Counts
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.sectionArray count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.sectionArray objectAtIndex:section];
}
Data Populated from
// Find out the path of recipes.plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"law2" ofType:#"plist"];
// Load the file content and read the data into arrays
self.dataArray = [NSArray arrayWithContentsOfFile:path];
//Sort the array by section
self.sortedArray = [self.dataArray sortedArrayUsingDescriptors:#[
[NSSortDescriptor sortDescriptorWithKey:#"Section" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:#"Title" ascending:YES]]];
//Section for sorting
self.sectionArray = [self.sortedArray valueForKeyPath:#"Section"];

Always you are sending index of the object. So please try to use this one
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [self.tableDataIndexTitles objectAtIndex:index];
}

Related

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

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;

iOS: Adding on/off control for only first two cells in the Grouped UITableView

I need to create a Grouped UITableView like showing in the below picture. I created a Grouped UITableView in XIB and added the relevant code as per below code.
It's a simple grouped UITableview.
I like to know, how can i add On/OFF Switch like Button (Pls refer the image Security header) only those first two cells and remaining will be UITableViewCellAccessoryDisclosureIndicator?
Could someone guide me on this please?
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// Do any additional setup after loading the view from its nib.
NSArray *arrTemp1 = [[NSArray alloc]initWithObjects:#"Quick Logon",#"Stay Logged On", nil];
NSArray *arrTemp2 = [[NSArray alloc]initWithObjects:#"Notifications",#"Text Messaging",#"Family Members",#"Social Media",nil];
NSArray *arrTemp3 = [[NSArray alloc]initWithObjects:#"Payment Accounts",nil];
NSArray *arrTemp4 = [[NSArray alloc]initWithObjects:#"Phone Nickname",#"Version",nil];
NSDictionary *temp =[[NSDictionary alloc]initWithObjectsAndKeys:arrTemp1,#"Security",arrTemp2,#"Profile & Preferences", arrTemp3,#"Payment Preferences", arrTemp4,#"About", 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);
}
#pragma mark Table Methods
- (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;
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
Add On/OFF Switch to the cell propotype and show/hide when it needed.
- (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;
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
cell.switch.hidden = indexPath.secton > 0;
cell.accessoryType = indexPath.secton > 0 ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
return cell;
}
You should create two different prototype cells in your xib with two different identifiers. In cellForRowAtIndexPath:, dequeue the one you want based on the section,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
static NSString *SwitchCellIdentifier = #"SwitchCellIdentifier";
NSArray *listData =[self.tableContents objectForKey:[self.sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell;
if (indexPath.section == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:SwitchCellIdentifier];
// configure the cell;
return cell;
}else{
cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
// configure the cell;
return cell;
}
}

Multiple UITableViews, One View, Two Filled, One Blank. What's the issue?

I have 3 tableViews in one view and for some reason two of them are showing data but one isn't, what's my issue?!!
I'm guessing the issue is in the cellForRowAtIndexPath declaration. Attached it is.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView==_titleTV) {
NSDictionary *dictionaryTwo = [_titleArray objectAtIndex:indexPath.section];
NSArray *arrayTwo = [dictionaryTwo objectForKey:#"data"];
NSString *cellValueTwo = [arrayTwo objectAtIndex:indexPath.row];
cell.textLabel.text = cellValueTwo;
}
if (tableView==_cuisineTV) {
NSDictionary *dictionary = [_cuisineArray objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"data"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}
else {
int storyIndex = [indexPath indexAtPosition: [indexPath length]-1];
cell.textLabel.text=[_favouritesArray objectAtIndex: storyIndex];
}
return cell;
}
What's the problem??
Thanks,
SebOH.
Try printing out the value of cellValueTwo to ensure its not a blank string:
NSLog(#"cellValueTwo value: %#",cellValueTwo);
Did you check to make sure the number of cells being created for _titleTV is correct with what you expect from - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section?

How do I load the data from my NSMutableDictionary to my UITableView

dictionaryOfWebsites = [[NSMutableDictionary alloc] init];
[dictionaryOfWebsites setObject:#"http://www.site1.com" forKey:#"Site1"];
[dictionaryOfWebsites setObject:#"http://www.site2.com" forKey:#"Site2"];
[dictionaryOfWebsites setObject:#"http://www.site3.com" forKey:#"Site3"];
[dictionaryOfWebsites setObject:#"http://www.site4.com" forKey:#"Site4"];
Above is my dictionary. I want to have a tableview where the text in the UITableViewCell will say "Site1" and the subtext will have the URL.
I know this will get me all the keys
NSArray *keys = [dictionaryOfWebsites allKeys];
// values in foreach loop
for (NSString *key in keys) {
NSLog(#"%# is %#",key, [dict objectForKey:key]);
}
you're help would be greatly appreciated
If my approach is not the best one, please let me know so I can learn from your recommendations.
Try
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[dictionaryOfWebsites allKeys] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Initialize cell of style subtitle
NSArray *keys = [[dictionaryOfWebsites allKeys]sortedArrayUsingSelector:#selector(compare:)];
NSString *key = keys[indexPath.row];
cell.textLabel.text = key;
cell.detailTextLabel.text = dictionaryOfWebsites[key];
return cell;
}
Edit : It is better to have an array of dictionaries for these kind of representation.
Each dictionary with two key value pairs Title and Subtitle.
self.dataArray = [NSMutableArray array];
NSDictionary *dict = #{#"Title":#"Site1",#"Subtitle":#"http://www.site1.com"};
[dataArray addObject:dict];
//Add rest of the dictionaries to the dataArray
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.dataArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Initialize cell of style subtitle
NSDictionary *dict = self.dataArray[indexPath.row];
cell.textLabel.text = dict[#"Title"];
cell.detailTextLabel.text = dict[#"Subtitle"];
return cell;
}
You could try:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell initialization code
NSString *title = [keys objectAtIndex:indexPath.row];
cell.textLabel.text = title;
cell.detailTextLabel.text = [dictionaryOfWebsites objectForKey:title];
return cell;
}
in that case declare keys array as a property.

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