unable to add data in picker view through nsmutablearray - iphone

i am loading data from database in nsmutableaaray
-(void)SeoPickerData
{
self.pickerArray = [[NSMutableArray alloc] init];
{
const char *sql = "select * from Main";
sqlite3_stmt *selectStatement;
int returnValue = sqlite3_prepare_v2(database1, sql, -1, &selectStatement, NULL);
if(returnValue == SQLITE_OK)
{
//loop all the rows returned by the query.
while(sqlite3_step(selectStatement) == SQLITE_ROW)
{
//int key = sqlite3_column_int(selectStatement, 0);
NSString *Term = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectStatement, 2)];
Container *myObject=[[Container alloc] InitWithTermId:Term];
[self.pickerArray addObject:myObject];
[myObject release];
}
}
else
{
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(database1) );
}
}
}
and i copy data in of array with another array like this
localArray = [[NSMutableArray alloc] init];
Container *classObj = [[Container alloc] init];
[classObj.seoArray removeAllObjects];
[classObj SeoPickerData];
//[localArray addObject:#"Red"];
self.localArray = classObj.pickerArray;
[self.view addSubview:pickerView];
when the array is load in uipickerview function like this
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [localArray objectAtIndex:row];
}
the error is accrued ,how can i add items in uipicker view?

Here's a possible error:
NSString *Term = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectStatement, 2)];
Container *myObject=[[Container alloc] InitWithTermId:Term];
[self.pickerArray addObject:myObject];
[myObject release];
You're adding Container objects to the array.
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [localArray objectAtIndex:row];
}
Then you return a Container object when you're expected to return an NSString.

Related

How to pass value of db to auto complete text filed?

I created auto complete text box my problem is that how to pass array is stored value which is retrive from db
When use _category detail my app will crash .
if i'm using NSArray with objects there is no problem.
When I debug code i found problem in search method plz help to solve my problem
Thank you so much
My function
- (void)viewDidLoad
{
self.categoryDetail = [CompanyDetailDatabase database].categoryDetail;
NSMutableArray *arrt = [[NSMutableArray alloc]init];
//arrt = [NSMutableArray arrayWithArray:_categoryDetail];
arrt=[NSArray arrayWithArray:_categoryDetail];
self.pastUrls = [[NSMutableArray alloc]initWithArray:arrt];
// self.pastUrls = [[NSMutableArray alloc] initWithObjects:#"Hello1",#"Hello2",#"Hello3", nil];
self.autocompleteUrls = [[NSMutableArray alloc] init];
autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 180, 280, 50) style:UITableViewStylePlain];
autocompleteTableView.delegate = self;
autocompleteTableView.dataSource = self;
autocompleteTableView.scrollEnabled = YES;
autocompleteTableView.hidden = YES;
[self.view addSubview:autocompleteTableView];
[txtProduct setDelegate:self];
}
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {
// Put anything that starts with this substring into the autocompleteUrls array
// The items in this array is what will show up in the table view
[autocompleteUrls removeAllObjects];
for(NSString *curString in pastUrls)
{
NSRange substringRangeLowerCase = [curString rangeOfString:[substring lowercaseString]];
NSRange substringRangeUpperCase = [curString rangeOfString:[substring uppercaseString]];
if (substringRangeLowerCase.length !=0 || substringRangeUpperCase.length !=0)
{
[autocompleteUrls addObject:curString];
}
}
autocompleteTableView.hidden =NO;
[autocompleteTableView reloadData];
}
#pragma mark UITextFieldDelegate methods
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
autocompleteTableView.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
#pragma mark UITableViewDataSource methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return autocompleteUrls.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
}
cell.textLabel.text = [autocompleteUrls objectAtIndex:indexPath.row];
return cell;
}
#pragma mark UITableViewDelegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
txtProduct.text = selectedCell.textLabel.text;
}
Now view of scene image
I'm not sure about your methods. But, it is very simple to achieve. First you've to insert some records in your database table. And, while editing on your UITextField you have to pass the text to your database table as sqlite query with your conditions and returns as NSArray or NSMutableArray Some code snippets -
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == listTableView)
{
recordsArray = [self getRecords:string];
if ([recordsArray count] == 0 || recordsArray == NULL)
{
[[[UIAlertView alloc] initWithTitle:nil message:#"No Records Were found" delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil, nil] show];
}
else
{
tableV.hidden = NO;
[tableV reloadData];
}
}
return YES;
}
Above will get your typed string and pass to database method named as getRecords with typed string.
-(NSMutableArray*)getRecords:(NSString *)srchString
{
NSMutableArray *mutArray = [[NSMutableArray alloc]init];
sqlite3 *servicesDB;
NSString *filePath=[AppDelegate dbPath];
if(sqlite3_open([filePath UTF8String], &servicesDB) == SQLITE_OK)
{
NSString *sqlStatement;
sqlStatement = [NSString stringWithFormat:#"SELECT * FROM Records WHERE record = '%%%#%%'", srchString];
const char *sql = [sqlStatement UTF8String];
sqlite3_stmt *select_statement;
if (sqlite3_prepare_v2(servicesDB, sql, -1, &select_statement, nil) == SQLITE_OK)
{
while (sqlite3_step(select_statement) == SQLITE_ROW)
{
char *record = (char *)sqlite3_column_text(select_statement, 0);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSString stringWithUTF8String:record] forKey:#"record"];
[mutArray addObject:[dict copy]];
}
}
else
{
NSLog(#"Error while fetching data. '%s'", sqlite3_errmsg(servicesDB));
}
sqlite3_finalize(select_statement);
}
sqlite3_close(servicesDB);
return mutArray;
}
Above database method will execute and fetch the data which are all having word whatever you're typed. You can find the details about LIKE clause here
You'll get your final result once the executions are completed. Simply find a sample project here

how to fetch data from sqlite database table in ios? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
i want to fetch data from my database table when i enter the name of the star in textfield the it give me all the quotes of that star for random names of star.
-(NSMutableArray *)searchAllQuotesOfStar
{
NSString *starName = [[NSString alloc] init];
// NSString *name = [NSString stringWithFormat:#"starName"];
NSMutableArray *starQuoteArray = [[NSMutableArray alloc] init];
NSString *sqlStr = [NSString stringWithFormat:#"SELECT quote FROM quotes where star like '%%starName%%'"];
//SELECT count(quote) from quotes where star like '%ac%'
sqlite3_stmt *ReturnStatement = (sqlite3_stmt *) [self getStatement:sqlStr];
while (sqlite3_step(ReturnStatement)==SQLITE_ROW)
{
#try
{
searchStarQuoteDC *searchQoute = [[searchStarQuoteDC alloc] init];
NSString *quote = [NSString stringWithUTF8String:(char*)sqlite3_column_text(ReturnStatement, 0)];
searchQoute.quote = quote;
// NSLog(#"%#", quote);
[starQuoteArray addObject:searchQoute];
}
#catch (NSException *ept) {
NSLog(#"Exception in %s, Reason: %#", __PRETTY_FUNCTION__, [ept reason]);
}
}
return starQuoteArray;
}
First Get Data From Sqlite Like this Below Code.
-(void)getdataMT
{
sqlite3 * database;
NSString *databasename=#"MathsTricks.sqlite"; // Your database Name.
NSArray * documentpath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);
NSString * DocDir=[documentpath objectAtIndex:0];
NSString * databasepath=[DocDir stringByAppendingPathComponent:databasename];
if(sqlite3_open([databasepath UTF8String], &database) == SQLITE_OK)
{
const char *sqlStatement = "SELECT * FROM Mathematicstricks"; // Your Tablename
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
[name removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
[name addObject:[NSString stringWithFormat:#"%s",(char *) sqlite3_column_text(compiledStatement, 0)]];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
And Stored it into Tableview
like this
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return name.count;
}
- (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];
}
cell.textLabel.text=[NSString stringWithFormat:#"%#",[name objectAtIndex:indexPath.row]];
return cell;
}
Try this.
I hope this is really helpful.
Add this code to databaseFlipsideViewController
//databaseFlipsideViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
detailController = segue.destinationViewController;
detailController.customerName = [keys objectAtIndex:indexPath.row];
NSLog(#"%#", detailController.customerName);
}
}
And my detailViewController code is this:
#implementation detailViewController
#synthesize customerLabel,code1Label,code2Label,dateLabel,customerName,code1Name;
//file path to database
-(NSString*)filePath {
NSArray*paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[paths objectAtIndex:0]stringByAppendingPathComponent:#"bp.sql"];
}
//open database
-(void)openDB {
if(sqlite3_open([[self filePath]UTF8String], &db) !=SQLITE_OK) {
sqlite3_close(db);
NSAssert(0, #"Databese failed to open");
}
else {
NSLog(#"database opened");
}
}
- (IBAction)back:(id)sender
{
[self.delegate detailViewControllerDidFinish:self];
}
- (void)viewDidLoad
{
[self openDB];
NSString*sql = [NSString stringWithFormat:#"SELECT theDate, customer,code1,code2 FROM summary WHERE key=\"%#\"", customerName];
const char *query_stmt = [sql UTF8String];
sqlite3_stmt*statement;
if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, nil)==SQLITE_OK) {
if (sqlite3_step(statement)==SQLITE_ROW) {
NSString *date = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
dateLabel.text = date;
NSString *customer = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
customerLabel.text = customer;
NSString *code1 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
code1Label.text = code1;
NSString *code2 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement,3)];
code2Label.text = code2;
}
sqlite3_finalize(statement);
[super viewDidLoad];
}
sqlite3_close(db);
}

Pulling values from a picker and converting to an int

I am trying to make a calculating app that consists of a 2-column picker. The left side of the picker are data values and the data values are being pulled from a plist with the price of each item. The other side of the picker is a string going from 1 to 64.
I'm trying to figure out how to take the string values of both parts of the picker and convert them into an int (so they can be multiplied and printed out)
Here's my code (in its entirety)
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath =[bundle pathForResource:#"worthList" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.dataValues = dictionary;
[dictionary release];
NSArray *components = [self.dataValues allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:#selector(compare:)];
self.values = sorted;
NSMutableArray *number =[[NSMutableArray alloc] init];
for(int x = 1; x < 65; x++)
{
NSString * numberString = [[NSString alloc] initWithFormat:#"%d",x];
[number addObject:numberString];
}
self.quantity = number;
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
self.doublePicker = nil;
self.dataValues = nil;
self.values = nil;
self.quantity = nil;
[self setDoublePicker:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)calculateItem:(id)sender
{
NSString *message = [[NSString alloc] initWithFormat:#""];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Thank you" message:message delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles: nil];
[alert show];
[alert release];
[message release];
}
#pragma mark -
#pragma Picker data source methods
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
-(NSInteger)pickerView:(UIPickerView *) pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == kValueComponent)
{
return [self.values count];
}
return [self.quantity count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent: (NSInteger)component
{
if (component == kValueComponent)
{
return [self.values objectAtIndex:row];
}
return [self.quantity objectAtIndex:row];
}
#end
Try this to convert your data string into an int and then do the calculation:
int = [yourString intValue];
Try this:
NSString *str=[NSString stringWithFormat:#"%#",[pickerArr objectAtIndex:row]];
int test=[str intValue];
HERE MINUTES AND SECONDS ARE ARRAY.
Delegate method of a picker.
You can use other delegate methods also.
Seconds and minutes are the array which loads the picker in your case use array which is feeded with plist.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
switch (component) {
case 0:
minuteTime =[minutes objectAtIndex:row] intValue];
break;
case 1:
secondTime = [[seconds objectAtIndex:row] intValue];
break;
}
}
You can also use this method to distinguish strings further.
NSArray *greenTime = [yourstring componentsSeparatedByString:#":"];
NSLog(#"Green Time : %#\nFirst : %#\nSecond : %#",greenTime,[greenTime objectAtIndex:0],[greenTime objectAtIndex:1]);

Obj-C, iOS, How do I sort by value and not key, sortedArrayUsingSelector, currently #selector(compare:)]

I need to sort by value instead of Key, I think....
Heres where I populate my arrarys
const char *sql = "select cid, category from Categories ORDER BY category DESC";
sqlite3_stmt *statementTMP;
int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if(error_code == SQLITE_OK) {
while(sqlite3_step(statementTMP) == SQLITE_ROW)
{
int cid = sqlite3_column_int(statementTMP, 0);
NSString *category = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statementTMP, 1)];
NSArray *arr=[[NSArray alloc]initWithObjects:category,nil];
[arrayTmp setObject:arr forKey:[NSString stringWithFormat:#"%i",cid]];
[self.cidList addObject:[NSString stringWithFormat:#"%i",cid]];
[category release];
[arr release];
}
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);
self.allCategories = arrayTmp;
[arrayTmp release];
Heres the method where the arrays are re-sorted.
- (void)resetSearch {
NSMutableDictionary *allCategoriesCopy = [self.allCategories mutableDeepCopy];
self.Categories = allCategoriesCopy;
[allCategoriesCopy release];
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
[keyArray addObject:UITableViewIndexSearch];
[keyArray addObjectsFromArray:[[self.allCategories allKeys]
sortedArrayUsingSelector:#selector(compare:)]];
self.keys = keyArray;
[keyArray release];
}
This is a problem i've had for some time, last time I looked at this I could find an altervative to sortedArrayUsingSelector compare?
EDIT
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [Categories objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SectionsTableIdentifier ];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier: SectionsTableIdentifier ] autorelease];
}
cell.textLabel.text = [nameSection objectAtIndex:row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [Categories objectForKey:key];
NSLog(#"the selected cid is = %i",[key intValue]);
selectButton.enabled = YES;
}
Anyone?
Your obviously attempting to construct an array for use in the -[UITableviewDatasource sectionIndexTitlesForTableView:]. As such, you need an array that looks like this (pseudo-code):
[UITableViewIndexSearch, 0_sectionTitle, 1_sectionTitle, 2_sectionTitle, ...]
I think your immediate problem is that you try to add the UITableViewIndexSearch string constant to the array before you sort which makes it impossible for it end up as the first element unless all your other elements sort below U.
The fix is simple, just add the constant after the sort. You can clean the code up while you're at it:
NSMutableArray *secIdx=[NSMutableArray arrayWithCapacity:[[self.allCategories allKeys] count]];
[secIdx addObjectsFromArray:[self.allCategories allKeys]];
[secIdx sortUsingSelector:#selector(compare:)];
[secIdx insertObject:UITableViewIndexSearch atIndex:0];
self.keys=secIdx;
Note that secIdx is autoreleased so you don't have to release it.
Aside from this problem, your code has a lot of unnecessary/dangerous elements that will make your app fragile and hard to maintain.
You are using a lot of init for objects that you could use autoreleased convenience methods for. The 'init`s poise the risk of memory leaks but give you no advantage.
You need to wrap scalar values in objects so they can be easily managed in collections.
You are using an unnecessary array.
You can rewrite the first block like so:
const char *sql = "select cid, category from Categories ORDER BY category DESC";
sqlite3_stmt *statementTMP;
int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if(error_code == SQLITE_OK) {
NSNumber *cidNum; //... move variable declerations outside of loop
NSString *category; //.. so they are not continously recreated
[self.allCategories removeAllObjects]; //... clears the mutable dictionary instead of replacing it
while(sqlite3_step(statementTMP) == SQLITE_ROW){
cidNum=[NSNumber numberWithInt:(sqlite3_column_int(statementTMP, 0))];
category=[NSString stringWithUTF8String:(char *)sqlite3_column_text(statementTMP, 1)];
//... adding the autoreleased category and cidNum to array/dictionary automatically retains them
[self.allCategories addObject:category forKey:cidNum];
[self.cidList addObject:cidNum];
//[category release]; ... no longer needed
//[arr release]; ... no longer needed
}
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);
//self.allCategories = arrayTmp; ... no longer needed
//[arrayTmp release]; ... no longer needed
Use -sortedArrayUsingComparator: (or -sortedArrayUsingFunction:context: if you can't use blocks). Example:
NSDictionary *categories = [self allCategories];
NSArray *keysSortedByValue = [[categories allKeys] sortedArrayUsingComparator:
^(id left, id right) {
id lval = [categories objectForKey:left];
id rval = [categories objectForKey:right];
return [lval compare:rval];
}];
You could make a small model class Category and implement compare inside of it, then sort an array of those objects using that compare:.
Here's some info - How to sort an NSMutableArray with custom objects in it?
Perhaps you're looking for NSSortDescriptor (and the corresponding sort method, -[NSArray sortedArrayUsingDescriptors]) and friends?
If I understood correctly then what you wish to do to get categories from database & display it on a tableView with alphabetical sorting, index on right & search bar on top. Ideally, you would like to display the Contacts application kind of a view. If that's correct, use below code for fetching items from DB & rebuilding (or resetting) it -
const char *sql = "select cid, category from Categories ORDER BY category DESC";
sqlite3_stmt *statementTMP;
NSMutableArray *arrayTmp = [[NSMutableArray alloc] init];
int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if(error_code == SQLITE_OK) {
while(sqlite3_step(statementTMP) == SQLITE_ROW) {
int cid = sqlite3_column_int(statementTMP, 0);
NSString *category = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statementTMP, 1)];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:category forKey:#"Category"];
[dict setObject:[NSNumber numberWithInt:cid] forKey:#"CID"];
[arrayTmp addObject:dict];
[dict release];
[category release];
}
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);
self.allCategories = arrayTmp;
[arrayTmp release];
And then rebuild the items using this function -
- (void)rebuildItems {
NSMutableDictionary *map = [NSMutableDictionary dictionary];
for (int i = 0; i < allCategories.count; i++) {
NSString *name = [[allCategories objectAtIndex:i] objectForKey:#"Category"];
NSString *letter = [name substringToIndex:1];
letter = [letter uppercaseString];
if (isdigit([letter characterAtIndex:0]))
letter = #"#";
NSMutableArray *section = [map objectForKey:letter];
if (!section) {
section = [NSMutableArray array];
[map setObject:section forKey:letter];
}
[section addObject:[allCategories objectAtIndex:i]];
}
[_items release];
_items = [[NSMutableArray alloc] init];
[_sections release];
_sections = [[NSMutableArray alloc] init];
NSArray* letters = [map.allKeys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
for (NSString* letter in letters) {
NSArray* items = [map objectForKey:letter];
[_sections addObject:letter];
[_items addObject:items];
}
}
Now, displaying items in tableView, use below methods -
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
if (_sections.count)
return _sections.count;
else
return 1;
}
- (NSInteger)tableView:(UITableView*)tableView sectionForSectionIndexTitle:(NSString *)title
atIndex:(NSInteger)index {
if (tableView.tableHeaderView) {
if (index == 0) {
[tableView scrollRectToVisible:tableView.tableHeaderView.bounds animated:NO];
return -1;
}
}
NSString* letter = [title substringToIndex:1];
NSInteger sectionCount = [tableView numberOfSections];
for (NSInteger i = 0; i < sectionCount; i++) {
NSString* section = [tableView.dataSource tableView:tableView titleForHeaderInSection:i];
if ([section hasPrefix:letter]) {
return i;
}
}
if (index >= sectionCount) {
return sectionCount-1;
} else {
return index;
}
}
- (NSArray*)lettersForSectionsWithSearch:(BOOL)withSearch withCount:(BOOL)withCount {
if (isSearching)
return nil;
if (_sections.count) {
NSMutableArray* titles = [NSMutableArray array];
if (withSearch) {
[titles addObject:UITableViewIndexSearch];
}
for (NSString* label in _sections) {
if (label.length) {
NSString* letter = [label substringToIndex:1];
[titles addObject:letter];
}
}
if (withCount) {
[titles addObject:#"#"];
}
return titles;
} else {
return nil;
}
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [self lettersForSectionsWithSearch:YES withCount:NO];
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
if (_sections.count) {
NSArray* items = [_items objectAtIndex:section];
return items.count;
} else {
return _items.count;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (_sections.count)
return [_sections objectAtIndex:section];
return nil;
}
- (id)tableView:(UITableView *)tableView objectForRowAtIndexPath:(NSIndexPath *)indexPath {
if (_sections.count) {
NSArray *section = [_items objectAtIndex:indexPath.section];
return [section objectAtIndex:indexPath.row];
} else {
return [_items objectAtIndex:indexPath.row];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create your UITableViewCell.
// Configure the cell.
NSDictionary *dict = [self tableView:tableView objectForRowAtIndexPath:indexPath];
cell.textLabel.text = [dict objectForKey:#"Category"];
cell.detailTextLabel.text = [NSString stringWithFormat:%d, [[dict objectForKey:#"CID"] intValue]];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (isSearching)
return nil;
NSString *title = #"";
if (_sections.count) {
title = [[_sections objectAtIndex:section] substringToIndex:1];
} else {
return nil;
}
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
view.backgroundColor = [UIColor colorWithRed:(58/255.0) green:(27/255.0) blue:(6/255.0) alpha:1.0];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 1, 50, 18)];
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:17.0];
label.text = title;
[view addSubview:label];
[label release];
return [view autorelease];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dict = [self tableView:tableView objectForRowAtIndexPath:indexPath];
NSLog(#"selected row id:%d, name:%#", [dict objectForKey:#"Category"], [[dict objectForKey:#"CID"] intValue]);
}
The rest part is implementing the UISearchBarDelegate and implementing searching of tableView which can be done using below code:
- (void)searchBar:(UISearchBar *)searchbar textDidChange:(NSString *)searchText {
[_sections removeAllObjects];
[_items removeAllObjects];
if([searchText isEqualToString:#""] || searchText == nil) {
[self rebuildItems];
return;
}
NSInteger counter = 0;
for(NSDictionary *dict in allCategories) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSRange r = [[dict objectForKey:#"Category"] rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(r.location != NSNotFound) {
if(r.location == 0) {
[_items addObject:dict];
}
}
counter++;
[pool release];
}
[contactList reloadData];
}
Hope this is what you're looking for.
On your sorting function u should try this:
NSArray *cntxt; //im not sure this is the correct type that ur using on keyArray
[keyArray addObjectsFromArray:[self.allCategories allKeys]];
[keyArray sortUsingFunction:compareFunction context:cntxt];
And the compare function you modify to your needs
NSInteger compareFunction(id x, id y, void *context) {
//NSArray *ctxt = context;
NSArray *c1 = x;
NSArray *c2 = y;
if ([c1 value] < [c2 value])
return NSOrderedDescending;
else if ([c1 value] > [c2 value])
return NSOrderedAscending;
else
return NSOrderedSame;
}
Edit: After reading your comments and after relooking at your code, it seems like that your keyArray as objects of the type NSString, so you should change:
NSInteger compareFunction(id x, id y, void *context) {
//NSString *ctxt = context;
NSString *c1 = x;
NSString *c2 = y;
NSComparisonResult result;
result = [c1 compare:c2];
if (result<0)
return NSOrderedAscending;
else if (result>0)
return NSOrderedDescending;
else
return NSOrderedSame;
}

Reload TaUITableViewbleView

I have a problem, I make a TabBAr application (with navigationbar), the bar bar is a list of favorits stored in an array.
My problem is that if I change ViewController and add object to array, when I come back to UITableView it isn't reloaded...
This is the class:
-
(void)viewDidLoad {
[super viewDidLoad];
[self readArgFromDatabaseSottoArgomenti];
[self VisualizzaPreferiti];
}
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
}
-(void) readArgFromDatabaseSottoArgomenti {
databasePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ARGOMENTI.sqlite"];
sqlite3 *databaseDesc;
// Init the argoments Array
arraySottoArgomenti = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &databaseDesc) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
// const char *sqlStatement = "select * from DESCRIZIONE ";
const char *sqlStatement = [[NSString stringWithFormat:#"SELECT * from DESCRIZIONE ORDER BY id"] UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(databaseDesc, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *aIDArgomento = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDescrizione = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aTesto = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
// Create a new argoments object with the data from the database
ContenutoObjectDescrizione *contenutoSottoArgomenti = [[ContenutoObjectDescrizione alloc] initWithName:aID idArgomento:aIDArgomento descrizione:aDescrizione testo:aTesto];
[arraySottoArgomenti addObject:contenutoSottoArgomenti];
[contenutoSottoArgomenti release];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(databaseDesc);
}
- (void) VisualizzaPreferiti {
int i;
NSUserDefaults *userPref = [NSUserDefaults standardUserDefaults];
array = [userPref objectForKey:#"array"];
NSLog(#"Retain Count %d Numero ID Array %d",[array retainCount],[array count]);
NSMutableArray *arrayOggettoPreferito;
arrayOggettoPreferito = [[NSMutableArray alloc] init];
ContenutoObjectDescrizione *oggetto = [[ContenutoObjectDescrizione alloc] init];
for (oggetto in arraySottoArgomenti) {
for (i=0; i<[array count]; i++) {
if ([[array objectAtIndex:i] intValue] == [oggetto.id intValue]) {
[arrayOggettoPreferito addObject:oggetto];
NSLog(#"ID %# IDMateria %# Titolo %#",oggetto.id,oggetto.idArgomento,oggetto.descrizione);
}
}
}
listaPref = arrayOggettoPreferito;
arrayOggettoPreferito=nil;
[arrayOggettoPreferito release];
[oggetto release];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [listaPref count];
}
// 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] autorelease];
}
ContenutoObjectDescrizione *oggettoCercato = [[ContenutoObjectDescrizione alloc] init];
oggettoCercato = [listaPref objectAtIndex:[indexPath row]];
cell.textLabel.text = oggettoCercato.descrizione;
NSLog(#"%#",oggettoCercato.descrizione);
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
TestoViewController *testoViewController = [[TestoViewController alloc] initWithNibName:#"TestoView" bundle:nil];
[self.navigationController pushViewController:testoViewController animated:YES];
ContenutoObjectDescrizione *oggettoCercato = [[ContenutoObjectDescrizione alloc] init];
oggettoCercato = [listaPref objectAtIndex:[indexPath row]];
testoViewController.idPreferito = oggettoCercato.id;
testoViewController.title = oggettoCercato.descrizione;
NSString *descrizioneWeb = oggettoCercato.testo;
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[testoViewController.vistaWeb loadHTMLString:descrizioneWeb baseURL:baseURL];
[testoViewController release];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
Simply calling reloadData doesn't make it do anything unless you update your datasource. In viewWillAppear, you will need to call VisualizzaPreferiti again before you call reloadData.