Accordion style tableview without using sections - iphone

I am interning for the summer on an iOS native app development team. They gave me a task of accomplishing removing/inserting cells in a tableview without using sections. I am struggling with the task if anyone could take a look at the code and try to help me out id be much appreciated. I am getting some removals and disappearances but it is not staying consistent, and it is adding cells that are already visible. (consistency in the sense that once i insert rows, row 3 is now row 5, and my modulo arithmetic gets thrown off.
I am very new to objective c so any advice / help would be much appreciated.
#implementation MasterViewController
NSMutableArray * levels;
NSMutableArray * array;
NSMutableIndexSet * expandedSections;
NSMutableDictionary * dict;
-(BOOL) loadFiles{
// NSFileManager * fileManager = [NSFileManager defaultManager];
if (!expandedSections) {
expandedSections = [[NSMutableIndexSet alloc]init];
}
array = [[NSMutableArray alloc]init];
levels = [[NSMutableArray alloc]init];
for (int i=0; i<20; i++) {
NSString * temp = [[NSString alloc]initWithFormat:#"This is row : %i ", i];
[array addObject:temp];
}
for (int i=0; i<20; i++) {
NSNumber * temp = [[NSNumber alloc]initWithInt:i];
[levels addObject:temp];
}
dict = [[NSMutableDictionary alloc]initWithObjects:array forKeys:levels];
NSLog(#"TEST: %#", [dict objectForKey:[levels objectAtIndex:1]]);
return YES;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Master", #"Master");
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadFiles];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender {
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([expandedSections containsIndex:section]) {
return [array count] +2;
}
return [array 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];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (!(indexPath.row %3)==0) {
cell.textLabel.text = [dict objectForKey:[levels objectAtIndex:indexPath.row]];
[cell setIndentationLevel:2];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.accessoryView = nil;
} else {
cell.textLabel.text = [dict objectForKey:[levels objectAtIndex:indexPath.row]];
[cell setIndentationLevel:0];
}
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (!self.detailViewController) {
self.detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
}
BOOL currentlyExpanded = [expandedSections containsIndex:indexPath.row];
//[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(#"CurrentlyExpanded : %d", currentlyExpanded);
NSLog(#"TEST: %#", [dict objectForKey:[levels objectAtIndex:indexPath.row ]]);
if ((indexPath.row %3)==0) {
// only first row toggles exapand/collapse
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSInteger section = indexPath.section;
BOOL currentlyExpanded = [expandedSections containsIndex:section];
NSInteger rows;
NSMutableArray *tmpArray = [NSMutableArray array];
if (currentlyExpanded) {
rows = 2;
[expandedSections removeIndex:section];
} else {
[expandedSections addIndex:section];
rows = 2;
}
for (int i=indexPath.row+1; i<=(indexPath.row + rows); i++) {
NSIndexPath *tmpIndexPath = [NSIndexPath indexPathForRow:i
inSection:section];
[tmpArray addObject:tmpIndexPath];
}
if (currentlyExpanded) {
[tableView deleteRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationTop];
} else {
[tableView insertRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationTop];
}
}
if ((indexPath.row %3)>0) {
NSDate *object = _objects[indexPath.row];
self.detailViewController.detailItem = object;
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
}
#end

Take a look at TLIndexPathTools. It greatly simplifies building dynamic tables like this. It does all the work calculating and performing the batch updates for you. Try running the Outline sample project. It demonstrates how to build an expandable tree without using sections. You can accomplish what you need by just building up a two-level tree.

Related

Open new UIView when select a row

I have a problem that is proving difficult to resolve.
I should open a new UITableView when clicked a cell in the table above.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ChoiceChampionViewController *choiceChampionViewController = [[ChoiceChampionViewController alloc] initWithNibName:#"ChoiceChampionViewController" bundle:nil];
NSString * ind = #".....";
NSString * number = ..;
ind = [ind stringByReplacingOccurrencesOfString:#"XX" withString:number];
[[NSUserDefaults standardUserDefaults] setValue:number forKey:#"Region"];
choiceChampionViewController.url = ind;
[self.view addSubview: choiceChampionViewController.view];
}
ChoiceChampionViewController is structured as follows:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
champion = [[NSMutableArray alloc] init ];
self.navigationItem.title = #"Here is some text to make the navBar big";
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
Method for process data
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [champion count];
}
- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
League * app = [[League alloc] init];
app = [champion objectAtIndex:[indexPath row]];
cell.textLabel.text = app.title;
return cell;
}
But it keeps giving me this error:
[ChoiceChampionViewController tableView:cellForRowAtIndexPath:]: message sent to deallocated instance.
Can we help me?
open that new UITableViewController or UIViewController with use of pushViewController for go in to new UIViewController like bellow...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;{
ChoiceChampionViewController * choiceChampionViewController = [[ChoiceChampionViewController alloc]initWithNibName:#"ChoiceChampionViewController" bundle:nil];
UIBarButtonItem *_backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleDone target:nil action:nil];
self.navigationItem.backBarButtonItem = _backButton;
[_backButton release],
_backButton = nil;
[self.navigationController pushViewController:choiceChampionViewController animated:YES];
[choiceChampionViewController release];
}
UPDATE :
also use this bellow structure for cellForRowAtIndexPath: method...
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
League * app = [[League alloc] init];
app = [champion objectAtIndex:[indexPath row]];
cell.textLabel.text = app.title;
return cell;
}

How to save selected rows from UITableview to NSString variable?

I am new to xcode and making my first iPhone app.
I have a UITableview with 8 rows in a tabbed screen. I have a code which let's the user select maximum 4 rows at a time and mark it with checks when selected.
Now, when I change the view and navigate to the next tab I want to save the text from these checked rows in a single NSString variable separated by commas.
Is it possible to do so? Thank you, any help is very much appreciated.
Here is the code of the first tab from where I want to save the selected rows.
#implementation Psychological
static int count = 0;
- (void)viewDidLoad {
[super viewDidLoad];
listOfItems = [[NSMutableArray alloc] init];
[listOfItems addObject:#"1 option"];
[listOfItems addObject:#"2 option"];
[listOfItems addObject:#"3 option"];
[listOfItems addObject:#"4 option"];
[listOfItems addObject:#"5 option"];
[listOfItems addObject:#"6 option"];
[listOfItems addObject:#"7 option"];
[listOfItems addObject:#"8 option"];
}
#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 [listOfItems 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];
}
// Configure the cell...
NSString *cellValue = [listOfItems objectAtIndex:indexPath.row];
cell.text = cellValue;
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) {
if(count < 4)
{
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedIndexes addObject:[NSNumber numberWithInt:indexPath.row]];
count++;
}
} else {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[selectedIndexes removeObject:[NSNumber numberWithInt:indexPath.row]];
count --;
}
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
- (void)dealloc {
[listOfItems release];
[super dealloc];
}
#end
the easiest way is make method wich will return string that you need. Method will look something like this:
- (NSString *) selectedItems {
NSMutableString *result = [NSMutableString string];
for (int i = 0; i < [itemsArray count]; i++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
[tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
[result appendFormat:#"%#",cell.textLabel.text];
}
}
if (result.length > 2) {
[result replaceCharactersInRange:NSMakeRange(result.length-1, 1) withString:#""];
}
return result;
}
To get this line in another view controller you should find Psychological view controller in navigationController.viewController and call this method.
- (void) method {
for (UIViewController *vc in self.navigationController.viewControllers) {
if ([vc isKindOfClass:[Psychological class]]) {
NSString *str = vc.selectedItems;
}
}
}
Hope the following code suits your requirement:
//didSelect method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) {
if(count < 4) {
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedIndexes addObject:[NSNumber numberWithInt:indexPath.row]];
count++;
}
} else {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[selectedIndexes removeObject:[NSNumber numberWithInt:indexPath.row]];
count --;
}
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
Declare the selectedCell globally to access in all tabs
NSMutableString *selectedCell = [[NSMutableString alloc]init]; //Should declare this string globally
//Use the following code in -viewWillDisappear Method or where you feel it fits (method that called when navigating from present class)
for(int i = 0; i < [selectedIndexes count]; i++){
[selectedCell appendString:[selectedIndexes objectAtIndex:i];
[selectedCell appendString:#","];
}
NSRange range = {[selectedCell length]-1,1};
[selectedCell deleteCharactersInRange:range];
NSMutableString *selectedRow=[NSMutableString alloc]init];
for(int i=0; i<[count];i++)
{
selectedRow=[arrayName objectAtIndex:row];
[selectedRow appendString:#","];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryNone) {
if(count<4){
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
[[listOfItems objectAtIndex:indexPath.row]setObject:#"YES" forKey:#"Selected"];
count++;
}
} else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
if(count>=0){
selectedCell.accessoryType = UITableViewCellAccessoryNone;
[[listOfItems objectAtIndex:indexPath.row]setObject:#"NO" forKey:#"Selected"];
count--;
}
}
replace above code and when you want to navigate your page at that time check whether Selected value yes or no if yes then pass that value otherwise leave it.
for (int i =0 ; i<[listOfItems count]; i++) {
if ([[[listOfItems objectAtIndex:i]valueForKey:#"Selected"]isEqualToString:#"YES"]) {
if ([selectedId length]==0) {
selectedId = [NSString stringWithFormat:#"%#",[[listOfItems objectAtIndex:i]valueForKey:#"user_id"]];
}else {
selectedId = [selectedId stringByAppendingFormat:#",%#",[[listOfItems objectAtIndex:i]valueForKey:#"user_id"]];
}
}
}
You may want to have a global array.
Store the selected values into that global array then it would be easy to display them elsewhere.. :-)
Create a new class, let's call it Option, and give it two properties. One is a NSString called name and the other is a BOOL called selected. Instead of having listOfItems as an array of strings, make it a list of Option objects. Have each Option keep track of whether or not it's currently selected.
Make the controller class that owns listOfItems into a UITabBarControllerDelegate and implement tabBarController:didSelectViewController: so that it builds the string and passes it to the next selected controller.

Persisting Checklists on a UITableView using NSUserDefults

I have a very simple table view which shows a list of days. Once the user selects which days are relevant to them this data is saved in NSUserdefaults. I then need the check marks to remain once the user has exited then re-entered the table view.
I am very close to getting my desired functionality - I can save the array of check marked items and get it to persist using NSUserDefaults but I don't know how to make these selections persist (keep a check mark next to the selected item) once a user has exited then re-entered the table view.
I know that I need to edit the cellForRowAtIndexPath method but I am not sure exactly what to do. Any help would be greatly appreciated.
I have attached my code below:
#import "DayView.h"
#implementation DayView
#synthesize sourceArray;
#synthesize selectedArray;
- (id)init
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
// Custom initialization
[[self navigationItem] setTitle:#"Days"];
[[self tableView] setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (void)viewWillDisappear:(BOOL)animated
{
// create a standardUserDefaults variable
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
// Convert array to string
NSString *time = [[selectedArray valueForKey:#"description"] componentsJoinedByString:#","];
// saving an NSString
[standardUserDefaults setObject:time forKey:#"string"];
NSLog(#"Disapear: %#", time);
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
// create a standardUserDefaults variable
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
// getting an NSString object
NSString *myString = [standardUserDefaults stringForKey:#"string"];
NSLog(#"Appear: %#", myString);
NSMutableArray * tempArray = [[NSMutableArray alloc] init];
[self setSelectedArray:tempArray];
[tempArray release];
NSArray * tempSource = [[NSArray alloc] initWithObjects:#"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday",nil];
[self setSourceArray:tempSource];
[tempSource release];
[self.tableView reloadData];
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.sourceArray 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];
}
NSString *time = [sourceArray objectAtIndex:indexPath.row];
cell.textLabel.text = time;
if ([self.selectedArray containsObject:[self.sourceArray objectAtIndex:indexPath.row]])
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
NSLog(#"Selected Days: %#", selectedArray);
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"Which times you are available?";
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self.selectedArray containsObject:[self.sourceArray objectAtIndex:indexPath.row]]){
[self.selectedArray removeObjectAtIndex:[self.selectedArray indexOfObject: [self.sourceArray objectAtIndex:indexPath.row]]];
}
else
{
[self.selectedArray addObject:[self.sourceArray objectAtIndex:indexPath.row]];
}
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)viewDidUnload
{
[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);
}
#end
Create your tempSource as follows:
NSMutableArray * tempSource = [[NSMutableArray alloc] init];
NSArray *daysOfWeek = [NSArray arrayWithObjects:#"Monday", #"tuestay", #"wednesday", #"thursday", #"friday", #"saturday", #"sunday",nil];
for (int i = 0; i < 7; i++)
{
NSString *dayOfWeek = [daysOfWeek objectAtIndex:i];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:dayOfWeek, #"day", [NSNumber numberWithBool:NO], #"isSelected",nil];
[tempSource addObject:dict];
}
[self setSourceArray:tempSource];
[tempSource release];
Then use this Array in cellForRow and didSelect as follows:
cellForRow
NSDictionary *dayOfWeekDictionary = [sourceArray objectAtIntex:indexPath.row];
cell.textLabel.text = [dayOfWeekDictionary objectForKey:#"day"];
if ([[dayOfWeekDictionary objectForKey:#"isSelected"] boolValue])
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
else
[cell setAccessoryType:UITableViewCellAccessoryNone];
didSelect
NSDictionary *dayOfWeekDictionary = [sourceArray objectAtIntex:indexPath.row];
if ([[dayOfWeekDictionary objectForKey:#"isSelected"] boolValue])
[dayOfWeekDictionary setObject:[NSNumber numberWithBool:NO] forKey:#"isSelected"];
else
[dayOfWeekDictionary setObject:[NSNumber numberWithBool:YES] forKey:#"isSelected"];
To save this Array use this statement:
[[NSUserDefaults standardUserDefaults] setObject:sourceArray forKey:#"array"];

how to search in table view in iphone

hi friend i get here some problem please me i want search string in table view by searchbar i create all function of searchbar then i call in viewdidload method but it not working why
i am creating NSMutableArray *tabledata;
i am passing all value of app.journeylist in tabledata but it not wotking and application will be crash this is my controller class
//
// TJourneylistController.m
// Journey
//
// Created by rocky on 3/17/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "TJourneylistController.h"
#import "TAddNewJourney.h"
#import "TJourneyListCell.h"
#import "JourneyAppDelegate.h"
#import "TJourneyTabBar.h"
#import "global.h"
#import "TPastJourneyTabBar.h"
#import "NewJourney.h"
#import "TStartnewjourney.h"
#import "TMapViewController.h"
#import "TShareController.h"
#import "TSpeedometerController.h"
#import "TReviewsController.h"
#define DATABASE_NAME #"journey"
#implementation TJourneylistController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
//self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(add_clicked:)];
app = (JourneyAppDelegate *)[[UIApplication sharedApplication]delegate];
sBar =[[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 320, 30)];
sBar.delegate=self;
[self.view addSubview:sBar];
searcheddata =[[NSMutableArray alloc]init];
tabledata =[[NSMutableArray alloc]init];
[tabledata addObject:app.journeyList];
app.journeyList=[[NSMutableArray alloc]init];
for(char c = 'A';c<='Z';c++)
[app.journeyList addObject:[NSString stringWithFormat:#"%cTestString",c]]; //list = [app.journeyList retain];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100.0;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [tabledata count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TJourneyListCell *cell =(TJourneyListCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TJourneyListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
NSLog(#"%#",cell);
}
NewJourney *newjoruneobject = [app.journeyList objectAtIndex:indexPath.row];
switch (indexPath.section) {
case 0:
cell.namelbl.text = newjoruneobject.journeyname;
cell.distancelbl.text = newjoruneobject.journeylocation;
cell.infolbl.text = newjoruneobject.journeydescription;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
break;
case 1:
cell.namelbl.text = #"Hello";
break;
default:
break;
}
return cell;
}
#pragma mark UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
// only show the status bar’s cancel button while in edit mode
sBar.showsCancelButton = YES;
sBar.autocorrectionType = UITextAutocorrectionTypeNo;
// flush the previous search content
[tabledata removeAllObjects];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
sBar.showsCancelButton = NO;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[tabledata removeAllObjects];// remove all data that belongs to previous search
if([searchText isEqualToString:#""]|| searchText==nil){
[myTableView reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in app.journeyList)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchText];
if(r.location != NSNotFound)
{
if(r.location== 0)//that is we are checking only the start of the names.
{
[tabledata addObject:name];
}
}
counter++;
[pool release];
}
[myTableView reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{ // if a valid search was entered but the user wanted to cancel, bring back the main list content
[tabledata removeAllObjects];
[tabledata addObjectsFromArray:app.journeyList];
#try
{
[myTableView reloadData];
}
#catch(NSException *e)
{
}
[sBar resignFirstResponder];
sBar.text = #"";
}
// called when Search (in our case “Done”) button pressed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
#pragma mark -
#pragma mark Table view delegate
- (void)dealloc {
[super dealloc];
//[self.tableView release];
[mLable1 release];
//[mLable2 release];
//[mLable3 release];
//[mLable4 release];
}
#end
Write this code into your .h file:
UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource
IBOutlet UISearchBar *sbArray;
IBOutlet UITableView *tvData;
Write this code into your .m file:
- (void)viewDidLoad
{
journeyList = [[NSMutableArray alloc] init];
FinalList = [[NSMutableArray alloc] init];
for(char c = 'A';c<='Z';c++)
[journeyList addObject:[NSString stringWithFormat:#"%cTestString",c]];
for(char c = 'A';c<='Z';c++)
[FinalList addObject:[NSString stringWithFormat:#"%cTestString",c]];
[tvData reloadData];
[super viewDidLoad];
}
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [FinalList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"anyCell"];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"anyCell"] autorelease];
}
cell.textLabel.text = [FinalList objectAtIndex:indexPath.row];
return cell;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)search
{
[search resignFirstResponder];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
FinalList = [[NSMutableArray alloc] init];
if([sbArray.text isEqualToString:#""]|| searchText == nil)
{
[tvData reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in journeyList)
{
NSRange r = [name rangeOfString:sbArray.text];
if(r.location != NSNotFound)
{
if(r.location== 0)//that is we are checking only the start of the names.
{
[FinalList addObject:name];
}
}
counter++;
}
NSLog(#"Counter :- '%d'",[FinalList count]);
[tvData reloadData];
}

My tableView only refresh from the UISearchBar only after an additional character is added

I have a tableView that refreshes with data from an array via the textDidChange function for UISearchBar. The data is correct, but it does not appear in the tableView until after hitting an additional character (so, for instance, if i typed 'Boise' into the search bar, nothing happens, but 'Boise1' will load two cities named 'Boise'..so it's one step behind).
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
//---if there is something to search for---
if ([searchText length] > 0) {
NSLog(#"greater than 0!");
isSearchOn = YES;
canSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self performSelector:#selector(someMethod) withObject:nil afterDelay:0];
//[NSThread detachNewThreadSelector:#selector(matchSearchText)
// toTarget:self withObject:nil];
//[self matchSearchText];
}
else {
//---nothing to search---
isSearchOn = NO;
canSelectRow = NO;
self.tableView.scrollEnabled = NO;
}
}
and in the method that is called:
- (void) someMethod {
NSLog(#"-------------");
NSLog(#"some Method whut!");
CityLookup *cityLookup = [[CityLookup alloc] findCity:searchBar.text];
// clear array
[tableCities removeAllObjects];
if ([cityLookup.citiesList count] > 0) {
tableCities = cityLookup.citiesList;
int size = [tableCities count];
NSLog(#"there are %d objects in the array", size);
}
[cityLookup release];
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:tableCities waitUntilDone:YES];
}
and finally the cellForRowAtIndexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
int size = [tableCities count];
NSLog(#"there are %d objects in the array NOW", size);
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSString *cellValue = [tableCities objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}