Compressed index sectionindextitlesfortableview - iphone

Loaded up my App in iOS7 SDK. My index list for my tableview is now compressed:
I can't seem to track down what could be going on. I don't set a size or length anywhere. Below is my code that assign the titles, but I'm guessing the problem must be somewhere else?
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
NSMutableArray *titleArray = [[NSMutableArray alloc] init];
if (BookHasSections())
{
NSInteger sections = tableView.numberOfSections;
for (int section = 0; section < sections; section++)
{
switch (section)
{
case 0:
[titleArray addObject:#"1"];
break;
default:
[titleArray addObject:[NSString stringWithFormat:#"%d0",section]];
break;
}
}
}
return titleArray;
}

Related

Add selected cells of different sections in different arrays, UICollectionView

I want to add selected cells of UICollectionView in arrays, section wise in different arrays, means different arrays for each section. The problem is this that number of sections are dynamic. Below is my code.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *seatV;
int cs;
NSString *secVal = [arrSeatSel objectAtIndex:indexPath.section];
NSArray *arrSplit = [secVal componentsSeparatedByString:#":"];
seatV = [arrSplit objectAtIndex:1];
cs = [seatV integerValue];
int v;
NSString *cnt = [NSString stringWithFormat:#"%#",[arrTot objectAtIndex:indexPath.section]];
v = [cnt intValue];
NSString *sect = [NSString stringWithFormat:#"%d", indexPath.section];
if(indexPath.item < v)
{
if([sectionInfo count] < cs)
{
itemPaths = [self.collectionView indexPathsForSelectedItems];
sectionInfo = [NSMutableArray arrayWithArray: [self.collectionView indexPathsForSelectedItems]];
[selectedItemsInfo setObject:sectionInfo forKey:sect];
cell=[self.collectionView cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"yellow_seat.png"]];
}
else
{
[self.collectionView deselectItemAtIndexPath:[NSIndexPath indexPathForItem:indexPath.row inSection:indexPath.section] animated:YES];
[sectionInfo removeAllObjects];
}
[self.collectionView deselectItemAtIndexPath:[NSIndexPath indexPathForItem:indexPath.row inSection:indexPath.section] animated:YES];
}
NSLog(#"section array:%#", sectionInfo);
NSLog(#"section array1:%#", sectionInfo1);
NSLog(#"selected seats dict:%#", selectedItemsInfo);
}
The array arrSeatSel is getting the number of sections and number of seats that can be choose from each section.
description of arr seatsel:(
"Family:2",
"Gold:3"
)
Here sections are 2 and cells that can be selected are 2. Similarly for other sections and in all cases.
arrTot is getting the total number of cells in each section
description of arrTot(
10,
10
)
array arrLevels are number of sections. and array itemPaths is adding the selected cells, and here the problem is, whichever section is it is adding selected cells, but each section has it's own limit of selecting cells. Hope you got my point, if anything clear ask freely.
In short i tell you what is happening here is there is seat map for different levels level 1, 2, etc. and for each level you can select limited seats, then those selected seats for different levels are required to add in different arrays.
Use a dictionary to store the details. section number becomes the keys and store an array of selected items corresponding to each keys
Here is outline
NSDictionary
Key:section0 value: array of selected items in section0
Key:section1 value: array of selected items in section1
Code
//Create a dictionary first
NSMutableDictionary *selectedItemsInfo = [NSMutableDictionary new];
// During selection
NSMutableArray *sectionInfo = [selectedItemsInfo objectForKey:indexPath.section];
if (sectionInfo == nil) {
NSMutableArray *array = [NSMutableArray array]
[array addObject: ] // add selected item
[selectedItemsInfo setObject:array forKey:indexPath.section];
}
else
{
[sectionInfo addObject: ] // add selected item
}
Edit (Imp code from discussion)
// Follow the below pattern
NSMutableArray *sectionInfo = [selectedItemsInfo objectForKey: [NSNumber numberWithInt:indexPath.section]];
if (sectionInfo == nil) {
NSMutableArray *array = [NSMutableArray array];
[array addObject: indexPath]; // add selected item
[selectedItemsInfo setObject:array forKey:[NSNumber numberWithInt:indexPath.section]];
}
else
{
// check the count
if([sectionInfo count] < cs)
{
[sectionInfo addObject: indexPath]; // add selected item
}
else
{
// No need to add the item. Deselect the cell
}
}
// To remove an item
sectionInfo = [selectedItemsInfo objectForKey: [NSNumber numberWithInt:indexPath.section]];
[sectionInfo removeObject:indexPath]

how to populate more tableview sections with one array

I'm working on a tableview that displays data about a company. I want to divide the data over 3 sections, to make it look more organized.
The data about a company is retreived from a mysql database and I receive it in one array, which looks like this:
{
companyAdress = "the street 9";
companyCity = "city";
companyFacebook = "facebook.com/companyname";
companyName = "name";
companyPhoneNumber = "0123 456 789";
companyTwitter = "www.twitter.com/companyname";
companyWebsite = "www.companyname.com";
companyZip = "0000 AA";
imageNumber = "3067913";
}
I want the companyName and imageNumber in the first section, the companyAdress, companyZip and companyCity in the second, and all the remaining variables in the third section.
I do not know how to properly do this, and I haven't found a useful answer/solution for this on SO or any other website I know.
How to I do this? any help, sample code and/or tutorial would be much appreciated, thank you in advance!
One approach would be to separate the data when you receive it into a two-dimensional array. So the array's first entry would be an array holding companyName and imageNumber, and so on.
With this implementation, numberOfSectionsInTableView would simply return myArray.count and numberOfRowsInSection would return myArray[section].count.
To access the appropriate values from there, you would do something like ((NSMutableArray*)myArray[indexpath.section])[indexpath.row]
You must use a Array of NSDictionary items,
then you get info for sections and tables rows.
adding a key for each record type.
This is a sample project for explain the use of NSArray and NSDictonary, I hope this help you.
You can download the xcode project from here http://www.germinara.it/download/FGTestTableView.zip and this is the result of the sample http://www.germinara.it/download/FGtesttableview.png
#import <UIKit/UIKit.h>
#interface FGViewController : UIViewController <UITableViewDataSource,UITableViewDelegate> {
NSMutableArray* records;
}
#property(nonatomic,strong) IBOutlet UITableView *tblRecordsList;
-(void) buildDataSource; //Build the datasource for the tableview
#end
#import "FGViewController.h"
#interface FGViewController ()
#end
#implementation FGViewController
#synthesize tblRecordsList;
- (void)viewDidLoad
{
[super viewDidLoad];
records = [[NSMutableArray alloc] init];
//Load data into array used as datasource
[self buildDataSource];
self.tblRecordsList.dataSource=self;
self.tblRecordsList.delegate=self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
//Load sample data
-(void) buildDataSource{
NSMutableDictionary* dict= nil;
[records removeAllObjects];
//Fill data source with your data
//Data to put on first section
dict=[NSMutableDictionary dictionaryWithCapacity:0];
[dict setObject:#"0" forKey:#"idsection"];
[dict setObject:#"company1" forKey:#"companyName"];
[dict setObject:#"picture1" forKey:#"imageNumber"];
[records addObject:dict]; //Add items to array
//Data to put on second section
dict=[NSMutableDictionary dictionaryWithCapacity:0];
[dict setObject:#"1" forKey:#"idsection"];
[dict setObject:#"address1" forKey:#"companyAdress"];
[dict setObject:#"zip1" forKey:#"companyZip"];
[dict setObject:#"city1" forKey:#"companyCity"];
[records addObject:dict]; //Add items to array
//Data to put on other section
dict=[NSMutableDictionary dictionaryWithCapacity:0];
[dict setObject:#"2" forKey:#"idsection"];
[dict setObject:#"facebook1" forKey:#"companyFacebook"];
[dict setObject:#"phone1" forKey:#"companyPhoneNumber"];
[dict setObject:#"twitter1" forKey:#"companyTwitter"];
[dict setObject:#"website1" forKey:#"companyWebsite"];
[records addObject:dict]; //Add items to array
}
//Get Dictionary using section key (idsection)
-(NSDictionary *) dictionaryForSection:(NSInteger) section{
for (NSDictionary *dict in records){
if(section == [[dict valueForKey:#"idsection"] intValue]){
return dict;
}
}
return nil;
}
//Table View Delegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"myCellReuseID"];
NSDictionary * dict = [self dictionaryForSection:indexPath.section]; //Get request dictionary info
//Process data for first section
if(indexPath.section == 0){
if(indexPath.row == 0)
cell.textLabel.text=[dict valueForKey:#"companyName"];
if(indexPath.row == 1)
cell.textLabel.text=[dict valueForKey:#"imageNumber"];
}
//Process data for second section
if(indexPath.section == 1){
if(indexPath.row == 0)
cell.textLabel.text=[dict valueForKey:#"companyAdress"];
if(indexPath.row == 1)
cell.textLabel.text=[dict valueForKey:#"companyZip"];
if(indexPath.row == 2)
cell.textLabel.text=[dict valueForKey:#"companyCity"];
}
//Process data for other section
if(indexPath.section == 2){
if(indexPath.row == 0)
cell.textLabel.text=[dict valueForKey:#"companyFacebook"];
if(indexPath.row == 1)
cell.textLabel.text=[dict valueForKey:#"companyPhoneNumber"];
if(indexPath.row == 2)
cell.textLabel.text=[dict valueForKey:#"companyTwitter"];
if(indexPath.row == 3)
cell.textLabel.text=[dict valueForKey:#"companyWebsite"];
}
return cell;
}
//Number of sections (first,second and other => 3)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (NSString *)tableView:(UITableView *)theTableView titleForHeaderInSection:(NSInteger)section
{
NSString * sectionTitle =#"";
switch (section) {
case 0:
sectionTitle = #"title first section";
break;
case 1:
sectionTitle = #"title second section";
break;
case 2:
sectionTitle = #"title other section";
break;
default:
break;
}
return sectionTitle;
}
//Count number of record for sections
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int nRecords=0;
int idSection =0;
//Count number of items for specified section
for (NSDictionary *dict in records){
idSection = [[dict valueForKey:#"idsection"] intValue];
if(section == idSection){
nRecords = [[dict allKeys] count] -1 ; //All dictionary Keys - 1 (the first key "idsection")
}
}
return nRecords;
}
#end

tableview will not update on phone

If this is a repost, I apologize, but I have been scouring the net and cant seem to find anything that works. I have a list of workouts that I display in a tableview that are gathered in plists in the bundle. There is a also a separate tab that I have that allows a user to build their own workouts and save them in the documents folder plist file. Once they are saved, they are added to the table view. In the simulator, everyuhting works fine. But on the actual device, it is not updated unless I close the program for an extended period of time, reload the program from xcode, or turn the phone off. I have tried adding [[self tableview] reload] to "viewDidLoad", "viewWillappear", and "viewDidAppear" and none of them work. Once again, the file is saved, the updating does work in the simulator, and it doesn't update in the phone right away. Any suggestions? Thanks.
Edit: i know it is a long piece of code, but should be straight forward (hopefully lol)
#import "BIDWODList.h"
#import "BIDWODDetails.h"
#define kFileName #"SavedDFWorkouts.plist"
#interface BIDWODList ()
#end
#implementation BIDWODList
#synthesize names;
#synthesize savedNames;
#synthesize keys;
#synthesize details;
#synthesize wodType;
#synthesize benchmarkGirls;
#synthesize theNewGirls;
#synthesize heroes;
#synthesize savedDFGWorkouts;
#synthesize chosenWOD;
#synthesize chosenDetails;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *buildBenchmarkGirls = [[NSMutableArray alloc] init];
NSMutableArray *buildTheNewGirls = [[NSMutableArray alloc] init];
NSMutableArray *buildHeroes = [[NSMutableArray alloc] init];
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistURL = [bundle URLForResource:#"CrossfitWOD" withExtension:#"plist"];
//put the contents of the plist into a NSDictionary, and then into names instance variable
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
self.names = dictionary;
//take all the keys in the dictionary and make an array out of those key names
self.keys = [self.names allKeys];
for (NSString *nameCheck in keys){
self.details = [names valueForKey:nameCheck];
if ([[self.details valueForKey:#"Type"] isEqualToString:#"The Benchmark Girls"]) {
[buildBenchmarkGirls addObject:nameCheck];
}else if ([[self.details valueForKey:#"Type"] isEqualToString:#"The New Girls"]) {
[buildTheNewGirls addObject:nameCheck];
}else {
[buildHeroes addObject:nameCheck];
}
}
NSString *filePath = [self dataFilePath];
NSMutableDictionary *savedWorkout = [[NSMutableDictionary alloc]initWithContentsOfFile:filePath];
self.savedNames = savedWorkout;
self.savedDFGWorkouts = [[savedWorkout allKeys] sortedArrayUsingSelector:#selector(compare:)];
self.benchmarkGirls = [buildBenchmarkGirls sortedArrayUsingSelector:#selector(compare:)];
self.theNewGirls = [buildTheNewGirls sortedArrayUsingSelector:#selector(compare:)];
self.heroes = [buildHeroes sortedArrayUsingSelector:#selector(compare:)];
//[[self tableView] reloadData]; //reloads the data in case a DFG workout was saved
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.names = nil;
self.keys = nil;
self.benchmarkGirls = nil;
self.theNewGirls = nil;;
self.heroes = nil;
self.details = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSString *)dataFilePath {
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFileName];
}
-(void)viewDidAppear:(BOOL)animated{
[[self tableView] reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 4;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (section == 0) {
return [benchmarkGirls count];
}else if (section == 1){
return [theNewGirls count];
}else if (section == 2){
return [heroes count];
}else{
return [savedDFGWorkouts count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SectionsTableIdentifier];
}
if (section == 0) {
cell.textLabel.text = [benchmarkGirls objectAtIndex:row];
}else if (section == 1) {
cell.textLabel.text = [theNewGirls objectAtIndex:row];
}else if (section == 2) {
cell.textLabel.text = [heroes objectAtIndex:row];
}else{
cell.textLabel.text = [savedDFGWorkouts objectAtIndex:row];
}
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return #" The Benchmark Girls";
}else if (section == 1){
return #"The New Girls";
}else if (section ==2){
return #"The Heroes";
}else{
return #"Saved DFG Workouts";
}
}
#pragma mark - Table view delegate
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
BIDWODDetails *destination = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
if (section == 0) {
self.chosenWOD = [self.benchmarkGirls objectAtIndex:row];
self.chosenDetails = [names objectForKey:chosenWOD];
}else if (section == 1) {
self.chosenWOD = [self.theNewGirls objectAtIndex:row];
self.chosenDetails = [names objectForKey:chosenWOD];
}else if (section ==2) {
self.chosenWOD = [self.heroes objectAtIndex:row];
self.chosenDetails = [names objectForKey:chosenWOD];
}else {
self.chosenWOD = [self.savedDFGWorkouts objectAtIndex:row];
self.chosenDetails = [savedNames objectForKey:chosenWOD];
}//end if
//self.chosenDetails = [names objectForKey:chosenWOD];
//[destination setValue:chosenWOD forKey:#"chosenWOD"];
//[destination setValue:chosenDetails forKey:#"chosenDetails"];
destination.chosenWOD = self.chosenWOD;
destination.chosenDetails = self.chosenDetails;
}
#end
Different behaviour between the simulator and the device is often related to incorrect case being used in filenames - the simulator isn't case sensitive, and the device is. Check that you have the correct case used everywhere you reference the plist file.
Alternatively, on the simulator you are able to write directly to the application bundle, but on the device this is not possible and you can only write to certain directories in your application's sandbox, typically the documents directory. You would normally copy a plist to the documents directory on first run, and use that file thereafter.
If I understand right your code you load plist file only in viewDidLoad, but most likely this function called only when you first time load your view. To make it work you should load plist
in viewDidAppear. Something like this:
- (void)viewDidAppear {
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistURL = [bundle URLForResource:#"CrossfitWOD" withExtension:#"plist"];
//put the contents of the plist into a NSDictionary, and then into names instance variable
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
self.names = dictionary;
//take all the keys in the dictionary and make an array out of those key names
self.keys = [self.names allKeys];
for (NSString *nameCheck in keys){
self.details = [names valueForKey:nameCheck];
if ([[self.details valueForKey:#"Type"] isEqualToString:#"The Benchmark Girls"]) {
[buildBenchmarkGirls addObject:nameCheck];
}else if ([[self.details valueForKey:#"Type"] isEqualToString:#"The New Girls"]) {
[buildTheNewGirls addObject:nameCheck];
}else {
[buildHeroes addObject:nameCheck];
}
}
NSString *filePath = [self dataFilePath];
NSMutableDictionary *savedWorkout = [[NSMutableDictionary alloc]initWithContentsOfFile:filePath];
self.savedNames = savedWorkout;
self.savedDFGWorkouts = [[savedWorkout allKeys] sortedArrayUsingSelector:#selector(compare:)];
[self.tableView reloadData];
}
If it works in the Simulator and does not on the phone, almost for sure the problem is a timing issue. Saving files on a real phone takes much longer than on the simulator.
You should do the following:
when you save a file, log it, and log the return code from the save. If the way you save does not provide a return code, use NSFileManager to verify the file is in fact where it should be and even the size of it. This takes time to do but you should do it.
when your table is asking for the number of this and that, log it, and lot what is returned. You may find that that this comes before the files are saved.
It takes time and effort, but if you start logging all relevant things, you can find it. I just spend 6 hours today tracking down a race condition I had thought could never happen, and it was only after looking at a huge trail of messages that I was able to see the problem.
Almost for sure you will see that either file is not saved, its not where you thought it was, or that the phone timing means some events happen later than they do in the Simulator.

UITableView insertRowsAtIndexPaths:

I have a Navigation Controller that contains a uitableview when I press on a row it pops a new view controller on the stack, which is used to display detail information in the detail view it makes a request from the server to get some response information then once the information is returned I use insertRowsAtIndexPaths: to display the information that is returned from the server.
This all works fine the first time, then when i press the back button and select a new row or the same row for viewing the detailed information once I the insertRowsAtIndexPaths: is called i get the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Here is the code for pushing the view on the stack:
VideoDetailViewController_iPhone *nextView = [[VideoDetailViewController_iPhone alloc] initWithNibName:#"VideoDetailViewController_iPhone" bundle:nil withVideo:rowData];
nextView.navController = navController;
[navController pushViewController:nextView animated:YES];
[nextView release];
Here is the code is executed once the information is returned from the server
- (void)fetchVideoDetail:(NSNotification *)notification {
hasLoadedResponses = YES;
NSArray *obj = (NSArray *)[notification object];
responses = [[obj valueForKey:#"responses"] mutableCopy];
//NSLog(#"RESPONSES: %#", responses);
if ([responses count] == 0) {
[tblView reloadData];
return;
}
NSMutableArray *indexes = [[NSMutableArray alloc] init];
int i = 0;
for (NSArray *x in responses) {
if (i > 0) {
//The reason for skipping the first one is because we will change that row once the table refreshes we just need to insert any rows after the first one.
[indexes addObject:[NSIndexPath indexPathForRow:i inSection:1]];
}
i++;
}
//NSLog(#"indexCount: %i", [indexes count]);
[tblView beginUpdates];
[tblView insertRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationBottom];
[tblView endUpdates];
//[tblView reloadData];
}
Here is the tableView methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (section == 0) {
return 1;
} else {
if ([responses count] == 0) {
NSLog(#"numberofrowsinsection: 1");
return 1;
} else {
NSLog(#"numberofrowsinsection: %i", [responses count]);
return [responses count];
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
VideoCell *cell = (VideoCell *)[tableView dequeueReusableCellWithIdentifier:CellClassName];
if (cell == nil) {
NSArray *topLevelItems = [cellLoader instantiateWithOwner:self options:nil];
cell = [topLevelItems objectAtIndex:0];
}
if (indexPath.section == 0) {
cell.lblTitle.text = [data title];
cell.lblDescription.text = [data videoDescription];
} else {
if ([responses count] == 0) {
if (!hasLoadedResponses) {
cell.lblTitle.text = #"";
cell.lblDescription.text = #"";
} else {
//Responses have been loaded
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.lblTitle.text = #"No responses to this video";
cell.lblDescription.text = #"Be the first to respond by selecting the \"Set as Destination\" button above";
}
} else {
//Display the response information
cell.lblTitle.text = [[responses objectAtIndex:indexPath.row] valueForKey:#"title"];
cell.lblDescription.text = [[responses objectAtIndex:indexPath.row] valueForKey:#"description"];
}
}
return cell;
}
Your datasource and number of rows are out of sync. When you insert the row, you have to increase the number of rows in the section at the same time. In this case you would have to increase the count of your array responses, which you are using in your numberOfRowsInSection method.

sort data and display in UItableview on iphone

i am using this query to get the data by ASC order
select * from list_tbl where cat_id=%d order by names ASC
now my table view shows data based on ASC order
then i used this to get the letters from A to Z on right side
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)help
{
return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:help];
}
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
now my problem is how to divide data based on section header like all A content goes to A and then B till Z and when user click on any alphabet on right side it should goes to that section
// UPDATES ///////////////
-(void)setUpRecordsForIndexing
{
for (NSString * recordName in appDelegate.catLists)//where app.catList contains all the value
{
NSString *firstLetter = ([recordName length] ==0)?miscKey:[[recordName substringToIndex:1]uppercaseString];
/*if(![firstLetter beginsWithCharacterInSet:[NSCharacterSet letterCharacterSet]] || [recordName isEqualToString:#""] || recordName == nil )
firstLetter = miscKey ;
*/
NSMutableArray *indexArray = [IndexedRecords objectForKey:firstLetter];
if (indexArray == nil)
{
indexArray = [[NSMutableArray alloc] init];
[IndexedRecords setObject:indexArray forKey:firstLetter];
[IndexLetters addObject:firstLetter];
[indexArray release];
}
[indexArray addObject:record];// this is not workking
// NSLog(#" index array is %#",indexArray);
}
}
my INDEXRECORD is not showing correct value
i can now divide the section based on ABCD but each sections are having same content , what i am doing wrong
for example: say RecordsArray contains your all the records, now in table view datasource method numberOfSectionsInTableView call one more method to index your all the records like below
-(void)setUpRecordsForIndexing
{
if(IndexedRecords)
{
[IndexedRecords release];
IndexedRecords = nil;
}
if(IndexLetters)
{
[IndexLetters release];
IndexLetters = nil;
}
IndexedRecords = [[NSMutableDictionary alloc] init];
IndexLetters = [[NSMutableArray alloc] init];
NSString *miscKey = #"#";
for (NSString * recordName in RecordsArray)
{
NSString *firstLetter = ([recordName length] ==0)?miscKey:[[recordName substringToIndex:1]uppercaseString];
if(![firstLetter beginsWithCharacterInSet:[NSCharacterSet letterCharacterSet]] || [recordName isEqualToString:#""] || recordName == nil )
firstLetter = miscKey ;
NSMutableArray *indexArray = [mIndexedRecords objectForKey:firstLetter];
if (indexArray == nil)
{
indexArray = [[NSMutableArray alloc] init];
[IndexedRecords setObject:indexArray forKey:firstLetter];
[IndexLetters addObject:firstLetter];
[indexArray release];
}
[indexArray addObject:record];
}
}
and in numberOfSectionsInTableView return the count of IndexLetters. I hope this will solve your problem.
While indexing your records, keep your records in a dictionary say IndexedRecords. Such that, for key "A" set the array of records begin with letter "A". And while populating the table view
[[IndexedRecords objectForKey:[IndexLetters objectAtIndex:indexPath.section]]objectAtIndex:indexPath.row]
IndexLetters is also an array containing your index letters for the current list.