I have a little problem resigning the keyboard. I have a table with two sections. In the second section, I load the class stationenStartCellNumber which has a UITextField.
When I press anywhere outside of the UITextField, I want the keyboard to resign as first responder, and thereby closing the keyboard. It works perfectly inside of my cell, but not on my UITableView.
This is my code:
stationenViewController.h:
#import <UIKit/UIKit.h>
#import "stationenStartCell.h"
#import "stationenAppDelegate.h"
#interface stationenViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
IBOutlet UITableView *theTable;
NSString *stationenPlistPath;
}
#property (nonatomic, retain) UITableView *theTable;
#property (nonatomic, retain) IBOutlet NSString *stationenPlistPath;
- (void)copyStationPlist;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
#end
stationenViewController.m:
#import "stationenViewController.h"
#import "chooseStationView.h"
#import "chooseArrDepView.h"
#import "stationenStartCellNumber.h"
#implementation stationenViewController
#synthesize theTable;
#synthesize stationenPlistPath;
- (void)viewWillAppear:(BOOL)animated {
[theTable reloadData];
[[[self navigationController] navigationBar] setAlpha:1];
[super viewWillAppear:animated];
}
- (void)viewDidLoad
{
NSArray *bikePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *bikeDocumentsDirectory = [bikePath objectAtIndex:0];
stationenPlistPath = [bikeDocumentsDirectory stringByAppendingPathComponent:#"stationen.plist"];
if(![[NSFileManager defaultManager] fileExistsAtPath:stationenPlistPath])
{
[self copyStationPlist];
}
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSUInteger returnInt = 2;
if (section == 1)
{
returnInt = 1;
}
return returnInt;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *returnString = [[NSString alloc] init];
if(section == 0)
{
returnString = #"Search station details";
}
else if (section == 1)
{
returnString = #"Search train number";
}
return returnString;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
static NSString *CellIdentifier = #"stationenStartCellID";
stationenStartCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if (cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"stationenStartCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[stationenStartCell class]])
{
cell = (stationenStartCell *)currentObject;
break;
}
}
}
[[cell theBackground] setBackgroundColor:[[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"stationenStartCell_Background.png"]]];
[[cell theImage] setImage:[UIImage imageNamed:#"icon_checkMark.png"]];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
if(indexPath.row % 4 == 0)
{
[[cell cellName] setText:NSLocalizedString(#"Choose station", #"Main page")];
[[cell chosenValue] setText:[prefs valueForKey:#"chosenStation"]];
NSLog(#"Log info: %#", [prefs valueForKey:#"chosenStation"]);
if([[prefs valueForKey:#"chosenStation"] isEqualToString:#""] || [prefs valueForKey:#"chosenStation"] == nil)
{
[[cell theImage] setAlpha:0.2];
}
else {
[[cell theImage] setAlpha:1];
}
}
if(indexPath.row % 4 == 1)
{
NSString *searchType = [prefs valueForKey:#"searchType"];
NSString *theValue = #"";
if([searchType isEqualToString:#"0"])
{
theValue = NSLocalizedString(#"Arrivals", #"Main page");
}
else if([searchType isEqualToString:#"1"])
{
theValue = NSLocalizedString(#"Departures", #"Main page");
}
if([theValue isEqualToString:#""])
{
[[cell theImage] setAlpha:0.2];
}
else {
[[cell theImage] setAlpha:1];
}
[[cell cellName] setText:NSLocalizedString(#"Choose departure/arrival", #"Main page")];
[[cell chosenValue] setText:theValue];
}
[UIView commitAnimations];
return cell;
}
else if (indexPath.section == 1)
{
static NSString *CellIdentifier = #"stationenStartCellNumber";
stationenStartCellNumber *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"stationenStartCellNumber" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[stationenStartCellNumber class]])
{
cell = (stationenStartCellNumber *)currentObject;
break;
}
}
}
[[cell theLabel] setText:#"Tåg nr:"];
return cell;
}
return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO];
if (indexPath.section == 0)
{
if(indexPath.row == 0)
{
chooseStationView *chooseStationViewController = [[chooseStationView alloc] initWithNibName:#"chooseStationView" bundle:nil];
[[self navigationController] pushViewController:chooseStationViewController animated:YES];
[chooseStationViewController release], chooseStationViewController = nil;
}
else {
chooseArrDepView *chooseArrDepViewController = [[chooseArrDepView alloc] initWithNibName:#"chooseArrDepView" bundle:nil];
[[self navigationController] pushViewController:chooseArrDepViewController animated:YES];
[chooseArrDepViewController release], chooseArrDepViewController = nil;
}
}
else {
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[theTable becomeFirstResponder];
[super touchesBegan:touches withEvent:event];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(void)copyStationPlist
{
NSString* bikesDictionaryPath = [[NSBundle mainBundle] pathForResource:#"stations" ofType:#"plist"];
NSDictionary* bikesDictionary = [[NSDictionary alloc] initWithContentsOfFile:bikesDictionaryPath];
NSArray *bikePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *bikeDocumentsDirectory = [bikePath objectAtIndex:0];
NSString *path = [bikeDocumentsDirectory stringByAppendingPathComponent:#"stations.plist"];
NSString * error;
NSData * data = [NSPropertyListSerialization dataFromPropertyList:bikesDictionary format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
[data writeToFile:path atomically:YES];
}
- (void)dealloc {
[super dealloc];
}
#end
Offcourse, the touchesBegan code does not work on a tableView because that one takes over. How can I resign the keyboard?
you can subclass UITableView and use it instead of standard UITableView. Why? Because You will be able to do smth like this
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[super touvhesBegan:touches withRvrnt:event];
}
this method will be called each time you touch your table. so you will be able to resign your textField as firstResponder inside this method.
You can create an invisible UIButton with an action to resign the keyboard.
Also, you will want to make sure to scroll your table view so that the keyboard does not cover your text field.
Related
I have a uitableview that's displaying multiple selections with a custom checkmark. When selected the rows value is save using NSUserDefaults. The problem is that despite the values being saved the checkmarks disappear from the table cell rows. I can't figure out why.
thanks for any help, I'm really stuck on this.
Here's the .h code:
#interface CategoriesViewController : UITableViewController {
NSString *selectedCategoryTableString;
NSString *jsonStringCategory;
int prev;
}
// arForTable array will hold the JSON results from the api
#property (nonatomic, retain) NSArray *arForTable;
#property (nonatomic, retain) NSMutableArray *arForIPs;
#property (nonatomic, retain) NSMutableArray *categorySelected;
#property (nonatomic, retain) NSString *jsonStringCategory;
#property(nonatomic, retain) UIView *accessoryView;
#end
and the .m code:
#implementation CategoriesViewController
#synthesize jsonStringCategory;
#synthesize arForTable = _arForTable;
#synthesize arForIPs = _arForIPs;
- (void)viewDidLoad
{
[super viewDidLoad];
self.arForIPs=[NSMutableArray array];
self.categorySelected = [[NSMutableArray alloc] init];
[self reloadMain];
self.tableView.allowsMultipleSelection = YES;
}
-(void) reloadMain {
jsonString = #"http:///******";
// Download the JSON
NSString *jsonString = [NSString
stringWithContentsOfURL:[NSURL URLWithString:jsonString]
encoding:NSStringEncodingConversionAllowLossy|NSUTF8StringEncoding
error:nil];
NSMutableArray *itemsTMP = [[NSMutableArray alloc] init];
// Create parser
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *results = [parser objectWithString:jsonString error:nil];
itemsTMP = [results objectForKey:#"results"];
self.arForTable = [itemsTMP copy];
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.arForTable 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 setFont:[UIFont fontWithName: #"Asap-Bold" size: 14.0f]];
[cell.detailTextLabel setFont:[UIFont fontWithName: #"Asap-Bold" size: 14.0f]];
cell.accessoryView.hidden = NO;
}
UIImageView *cellAccessoryImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon-tick.png"]] ;
UIImageView *cellAccessoryNoneImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#""]] ;
if([self.arForIPs containsObject:indexPath]){
cell.accessoryView = cellAccessoryImageView;
} else {
cell.accessoryView = cellAccessoryNoneImageView;
}
// Get item from tableData
NSDictionary *item = (NSDictionary *)[_arForTable objectAtIndex:indexPath.row];
// encoding fix
NSString *utf8StringTitle = [item objectForKey:#"name"];
NSString *correctStringTitle = [NSString stringWithCString:[utf8StringTitle cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding];
cell.textLabel.text = [correctStringTitle capitalizedString];
NSNumber *num = [item objectForKey:#"id"];
cell.detailTextLabel.text = [num stringValue];
cell.detailTextLabel.hidden = YES;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if([self.arForIPs containsObject:indexPath]){
[self.arForIPs removeObject:indexPath];
[self.categorySelected removeObject:[[self.arForTable objectAtIndex:indexPath.row] objectForKey:#"id"]];
} else {
[self.arForIPs addObject:indexPath];
[self.categorySelected addObject:[[self.arForTable objectAtIndex:indexPath.row] objectForKey:#"id"]];
NSLog(#"%# categorySelected",self.categorySelected);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(#"%# defaults categorySelected",[defaults arrayForKey:#"selectedCategoryTableString"]);
NSString *string = [self.categorySelected componentsJoinedByString:#","];
[defaults setObject:string forKey:#"selectedCategoryTableString"];
NSLog(#"%# STRING",string);
}
[tableView reloadData];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:NO];
[self.navigationController setNavigationBarHidden:YES animated:NO];
self.navigationController.toolbarHidden = YES;
}
First of all your code has lots of memory leaks, please do use the static analyzer and/or instruments to fix them, few for them are pretty obvious like you initialized the SBJSON parser and did not release it, itemsTMP is another.
I have rewritten your code to be much more efficient and memory friendly:
#interface CategoriesViewController : UITableViewController
{
NSArray *_items;
NSMutableArray *_selectedItems;
UIImageView *cellAccessoryImageView;
}
#end
#implementation CategoriesViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_selectedItems = [NSMutableArray new];
cellAccessoryImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon-tick.png"]] ;
[self reloadMain];
self.tableView.allowsMultipleSelection = YES;
}
- (void)reloadMain
{
NSString *jsonString = #"http:///******";
// Download the JSON
jsonString = [NSString
stringWithContentsOfURL:[NSURL URLWithString:jsonString]
encoding:NSStringEncodingConversionAllowLossy|NSUTF8StringEncoding
error:nil];
// Create parser
SBJSON *parser = [SBJSON new];
NSDictionary *results = [parser objectWithString:jsonString error:nil];
if (_items) [_items release];
_items = [[results objectForKey:#"results"] copy];
[parser release];
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_items 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] autorelease];
[cell.textLabel setFont:[UIFont fontWithName: #"Asap-Bold" size: 14.0f]];
[cell.detailTextLabel setFont:[UIFont fontWithName: #"Asap-Bold" size: 14.0f]];
cell.accessoryView.hidden = NO;
}
NSDictionary *item = [_items objectAtIndex:indexPath.row];
if ([_selectedItems containsObject:item])
{
// preloaded image will help you have smoother scrolling
cell.accessoryView = cellAccessoryImageView;
}
else
{
cell.accessoryView = nil;
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Get item from tableData
cell.textLabel.text = [[NSString stringWithCString:[[item objectForKey:#"name"] cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding] capitalizedString];
cell.detailTextLabel.text = [[item objectForKey:#"id"] stringValue];
cell.detailTextLabel.hidden = YES;
item = nil;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *item = [_items objectAtIndex:indexPath.row];
if ([_selectedItems containsObject:item])
{
[_selectedItems removeObject:item];
}
else
{
[_selectedItems addObject:item];
}
item = nil;
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (void)dealloc
{
[_selectedItems release];
[cellAccessoryImageView release];
[super dealloc];
}
#end
Since in your table there is only one section. Try this approach and this will help you certainly.
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath write following code;
if([self.arForIPs containsObject:[NSNumber numberWithInt:indexPath.row]]){
cell.accessoryView = cellAccessoryImageView;
} else {
cell.accessoryView = cellAccessoryNoneImageView;
}
And in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath write code as below,
if([self.arForIPs containsObject:[NSNumber numberWithInt:indexPath.row]]){
[self.arForIPs removeObject:[NSNumber numberWithInt:indexPath.row]];
} else {
[self.arForIPs addObject:[NSNumber numberWithInt:indexPath.row]]
}
I'm trying to do search but its not working for me perfectly .What i need that when I enter B then i should get all the words that starts with B . I'm still wondering where i'm doing wrong. i'm very new to ios.
here is my code :-
ContactViewController.h
#import <UIKit/UIKit.h>
#interface ContactViewController :
UIViewController<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate>
{
UISearchBar* searchBar;
IBOutlet UITableView* contactTableView;
NSMutableArray *listOfItems;
NSMutableArray *copyListOfItems;
NSArray *content;
NSArray *indices;
NSArray* contacts;
BOOL searching;
BOOL letUserSelectRow;
}
-(void)btn_AddContact;
#end
ContactViewController.m
#import "ContactViewController.h"
#import "AddContactsViewController.h"
#import "CustomCell.h"
#import "DataGenerator.h"
#interface ContactViewController ()
#end
#implementation ContactViewController
- (void)viewDidLoad
{
[super viewDidLoad];
const NSInteger searchBarHeight = 45;
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320,
searchBarHeight)];
[self.view addSubview:searchBar];
searchBar.delegate = self;
[self.view addSubview:searchBar];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:#"Refresh"
style:UIBarButtonItemStyleBordered target:self action:#selector(onAddContact)];
self.navigationItem.rightBarButtonItem = addButton;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:20.0];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor whiteColor]; // change this color
self.navigationItem.titleView = label;
label.text = NSLocalizedString(#"All Contacts", #"");
[label sizeToFit];
content = [DataGenerator wordsFromLetters];
indices = [[content valueForKey:#"headerTitle"] retain];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [content count];
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section {
return [[[content objectAtIndex:section] objectForKey:#"rowValues"] 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:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
if(searching) {
cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[NSString stringWithFormat:#"%# %# %#",
#"pauline.abraham#gmail.com", #" |",#"123456777"] ;
}else {
cell.textLabel.text = [[[content objectAtIndex:indexPath.section]
objectForKey:#"rowValues"]
objectAtIndex:indexPath.row];
//cell.detailTextLabel.numberOfLines=2;
//cell.detailTextLabel.lineBreakMode=NSLineBreakByWordWrapping;
cell.detailTextLabel.text=[NSString stringWithFormat:#"%# %# %#",
#"pauline.abraham#gmail.com", #" |",#"123456777"] ;
}
return cell;
}
- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:
(NSInteger)section {
return [[content objectAtIndex:section] objectForKey:#"headerTitle"];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [content valueForKey:#"headerTitle"];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:
(NSString *)title atIndex:(NSInteger)index {
return [indices indexOfObject:title];
}
-(void)onAddContact
{
// AddContactsViewController* add = [[AddContactsViewController alloc]
initWithNibName:#"AddContactsViewController" bundle:nil];
// [self.navigationController pushViewController:add animated:YES];
}
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
if(searching)
return;
searching = YES;
letUserSelectRow = NO;
[contactTableView setScrollEnabled:NO];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self
action:#selector(btn_DoneSearch)];
}
-(void)btn_DoneSearch
{
searchBar.text = #"";
[searchBar resignFirstResponder];
searching = NO;
letUserSelectRow = YES;
[contactTableView setScrollEnabled:YES];
self.navigationItem.rightBarButtonItem = nil;
[contactTableView reloadData];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
//Remove all objects first.
[copyListOfItems removeAllObjects];
if([searchText length] > 0){
searching = YES;
letUserSelectRow = YES;
[contactTableView setScrollEnabled:YES];
[self searchTableView];
}else {
searching = NO;
letUserSelectRow = NO;
[contactTableView setScrollEnabled:NO];
}
[contactTableView reloadData];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self searchTableView];
}
-(void)searchTableView
{
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in content)
{
NSArray *array = [dictionary objectForKey:#"rowValues"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText
options:NSCaseInsensitiveSearch];
if (titleResultsRange.length>0)
{
[copyListOfItems addObject:sTemp];
NSLog(#"lenght : %d",titleResultsRange.length );
}
}
searchArray = nil;
}
#end
see this below code also you not add the rows related searched data put this condition in below 3 delegate method of UITableView also
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (searching)
return 1;
else
return [content count];
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (searching)
return [copyListOfItems count];
else
return [[[content objectAtIndex:section] objectForKey:#"rowValues"] count] ;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if(searching)
return #"";
else
return [[content objectAtIndex:section] objectForKey:#"headerTitle"];
}
first .h
#interface PersonnelViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
NSMutableArray *personnelData;
IBOutlet UITextField *tableCellText;
IBOutlet UITableView *personTableView;
IBOutlet UINavigationItem *navItem;
}
#property (nonatomic, retain) NSMutableArray *personnelData;
-(IBAction)addRowToTableView;
-(IBAction)editTable;
-(NSString *)personDataFilePath;
-(IBAction)endText;
-(IBAction)done;
first .m
#implementation PersonnelViewController
#synthesize personnelData;
-(IBAction)done{
[self dismissModalViewControllerAnimated:YES];
}
- (void)viewDidLoad {
NSArray *archivedArray = [NSKeyedUnarchiver unarchiveObjectWithFile:[self personDataFilePath]];
if (archivedArray == nil) {
personnelData = [[NSMutableArray alloc] init];
} else {
personnelData = [[NSMutableArray alloc] initWithArray:archivedArray];
}
}
- (IBAction)addRowToTableView {
[personnelData addObject:tableCellText.text];
[self personDataFilePath];
[personTableView reloadData];
}
- (IBAction)editTable {
UIBarButtonItem *leftItem;
[personTableView setEditing:!personTableView.editing animated:YES];
if (personTableView.editing) {
leftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(editTable)];
} else {
leftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editTable)];
}
navItem.rightBarButtonItem = leftItem;
[self personDataFilePath];
[personTableView reloadData];
}
- (IBAction)endText {
}
- (NSInteger)numberOfSectionInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [personnelData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"] autorelease];
}
cell.textLabel.text = [personnelData objectAtIndex:indexPath.row];
return cell;
}
- (NSString *)personDataFilePath {
NSString *personDataFilePath;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
personDataFilePath = [[documentDirectory stringByAppendingPathComponent:#"applicationData.plist"] retain];
return personDataFilePath;
}
- (void)saveData1 {
[NSKeyedArchiver archiveRootObject:[personnelData copy] toFile:[self personDataFilePath]];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[personnelData removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath {
NSString *item = [[personnelData objectAtIndex:fromIndexPath.row] retain];
[personnelData removeObject:item];
[personnelData insertObject:item atIndex:toIndexPath.row];
[item release];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)dealloc {
[super dealloc];
}
#end
Second .h
#interface ApparatusViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *apparatusData;
IBOutlet UITextField *tableCellText;
IBOutlet UITableView *mainTableView;
IBOutlet UINavigationItem *navItem;
}
#property (nonatomic, retain) NSMutableArray *apparatusData;
-(IBAction)addRowToTableView;
-(IBAction)editTable;
-(NSString *)apparatusDataFilePath;
-(IBAction)endText;
-(IBAction)done;
#end
Second .m
#implementation ApparatusViewController
#synthesize apparatusData;
-(IBAction)done{
[self dismissModalViewControllerAnimated:YES];
}
- (void)viewDidLoad {
NSArray *arichvedArray = [NSKeyedUnarchiver unarchiveObjectWithFile:[self apparatusDataFilePath]];
if (arichvedArray == nil) {
apparatusData = [[NSMutableArray alloc] init];
} else {
apparatusData = [[NSMutableArray alloc] initWithArray:arichvedArray];
}
}
- (IBAction)addRowToTableView {
[apparatusData addObject:tableCellText.text];
[self apparatusDataFilePath];
[mainTableView reloadData];
}
- (IBAction)editTable {
UIBarButtonItem *leftItem;
[mainTableView setEditing:!mainTableView.editing animated:YES];
if (mainTableView.editing) {
leftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(editTable)];
} else {
leftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editTable)];
}
navItem.rightBarButtonItem = leftItem;
[self apparatusDataFilePath];
[mainTableView reloadData];
}
- (IBAction)endText {
}
- (NSInteger)numberOfSectionInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [apparatusData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"] autorelease];
}
cell.textLabel.text = [apparatusData objectAtIndex:indexPath.row];
return cell;
}
- (NSString *)apparatusDataFilePath {
NSString *apparatusDataFilePath;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
apparatusDataFilePath = [[documentDirectory stringByAppendingPathComponent:#"applicationData.plist"] retain];
return apparatusDataFilePath;
}
- (void)saveData {
[NSKeyedArchiver archiveRootObject:[apparatusData copy] toFile:[self apparatusDataFilePath]];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[apparatusData removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath {
NSString *item = [[apparatusData objectAtIndex:fromIndexPath.row] retain];
[apparatusData removeObject:item];
[apparatusData insertObject:item atIndex:toIndexPath.row];
[item release];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)dealloc {
[super dealloc];
}
#end
The data seems to be loading the same data into each table. How do I fix this.
You are loading "applicationData.plist" in both views!
I have a question about adding XML to the searchbar in a tableview. I can get all the external XML file to load in the tableview, but when I hit the searchbar up top, and hit a letter, it crashes.
I think it's something really simple that I'm doing wrong. In my RootViewController, there's a function called searchTableView. I feel like that's where it's not picking up the search items. I think it's somewhere around the objectForKey:#"title". When I debug, I get this error message also: "NSCFArray objectForKey unrecognized selector". Here's my searchTableView function:
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSArray *array = [dictionary objectForKey:#"title"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
Ok figured it out. For some reason this was really hard to find documentation how to do this.
Here's my RootViewController.m below.
My pList is configured as:
Root (Array)
Item0 (Dictionary)
Name (String)
Item1 (Dictionary)
Name (String)..
Here's my code, hopefully this helps anyone else looking for help on this:
#implementation RootViewController
#synthesize listOfItems, copyListOfItems;
- (void)viewDidLoad {
[super viewDidLoad];
//Initialize the array.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"plistArray" ofType:#"plist"];
NSMutableArray* tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
self.listOfItems = tmpArray;
[tmpArray release];
//Initialize the copy array.
copyListOfItems = [[NSMutableArray alloc] init];
//Set the title
self.navigationItem.title = #"Search";
//Add the search bar
self.tableView.tableHeaderView = searchBar;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searching = NO;
letUserSelectRow = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (searching)
return 1;
else
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (searching)
return [copyListOfItems count];
else {
//Number of rows it should expect should be based on the section
return [listOfItems count];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the selected country
NSString *selectedCountry = nil;
if(searching)
selectedCountry = [copyListOfItems objectAtIndex:indexPath.row];
else {
// Navigation logic may go here. Create and push another view controller.
}
NSDictionary *dictionary = [self.listOfItems objectAtIndex:indexPath.row];
FoodDetail *dvController = [[FoodDetail alloc] initWithNibName:#"FoodDetail" bundle:nil andDictionary: dictionary];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
}
// 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] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
if(searching)
cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
else {
cell.textLabel.text = [[self.listOfItems objectAtIndex:indexPath.row]
objectForKey:#"Name"];
}
return cell;
}
- (NSIndexPath *)tableView :(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(letUserSelectRow)
return indexPath;
else
return nil;
}
#pragma mark -
#pragma mark Search Bar
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
//This method is called again when the user clicks back from the detail view.
//So the overlay is displayed on the results, which is something we do not want to happen.
if(searching)
return;
//Add the overlay view.
if(ovController == nil)
ovController = [[OverlayViewController alloc] initWithNibName:#"OverlayView" bundle:[NSBundle mainBundle]];
CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
//Parameters x = origion on x-axis, y = origon on y-axis.
CGRect frame = CGRectMake(0, yaxis, width, height);
ovController.view.frame = frame;
ovController.view.backgroundColor = [UIColor grayColor];
ovController.view.alpha = 0.5;
ovController.rvController = self;
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = YES;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
//Add the done button.
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self action:#selector(doneSearching_Clicked:)] autorelease];
}
- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
//Remove all objects first.
[copyListOfItems removeAllObjects];
if([searchText length] > 0) {
[ovController.view removeFromSuperview];
searching = YES;
letUserSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self searchTableView];
}
else {
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = NO;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
}
[self.tableView reloadData];
}
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {
[self searchTableView];
}
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSString *text1 = [dictionary objectForKey:#"Name"];
[searchArray addObject:text1];
}
NSLog(#"%s: searchArray=%#", __func__, searchArray);
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
- (void) doneSearching_Clicked:(id)sender {
searchBar.text = #"";
[searchBar resignFirstResponder];
letUserSelectRow = YES;
searching = NO;
self.navigationItem.rightBarButtonItem = nil;
self.tableView.scrollEnabled = YES;
[ovController.view removeFromSuperview];
[ovController release];
ovController = nil;
[self.tableView reloadData];
}
- (void)dealloc {
[ovController release];
[copyListOfItems release];
[searchBar release];
[listOfItems release];
[super dealloc];
}
#end
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;
}