Could anyone give me a point in the right direction on how I should do this:
This sample from the Weather Channel shows what I would like to do. I just want to have a Table View in which someone could search for a city. I'm not sure where to get those resources and how to do it.
You can find the World City List from MaxMind.
Is it the resource you are looking for?
Create table view and search bar. You have to implement their delegates UISearchBarDelegate,UITableViewDataSource,UITableViewDelegate.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar1
{
searchBar.showsSearchResultsButton = YES;
searchBar.showsCancelButton = YES;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
// flush the previous search content
//Implement some code
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar1
{
searchBar.showsCancelButton = NO;
searchBar.showsSearchResultsButton = NO;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if([searchText isEqualToString:#""]||searchText==nil){
[yourTable reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in yourArray)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchText options:NSCaseInsensitiveSearch];
// NSRange r = [name rangeOfString:searchText];
// NSRange r = [name ];
if(r.location != NSNotFound)
{
//Implement the code.
}
counter++;
[pool release];
}
[yourTable reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar1
{
// if a valid search was entered but the user wanted to cancel, bring back the main list content
// Implement some code
#try{
[yourTable reloadData];
}
#catch(NSException *e){
}
[searchBar resignFirstResponder];
searchBar.text = #"";
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar1
{
[searchBar1 resignFirstResponder];
}
I have give to you incomplete methods and you can implement what you want to do.
I think it will be helpful to you.
Related
In my app, i have a search bar in my contact list page tableview. now my code searches the list based on any letter even if the search text is at the middle of the firstname or lastname. But i want it to search only from the beginning. For example., the word "sh" should pull only "Shiva", "Sheela", etc., but not "sathish", "suresh" etc., can anyone help me on this?
and my code is
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText
{
//---if there is something to search for---
if ([searchText length] > 0)
{
isSearchOn = YES;
canSelectRow = YES;
self.ContactTableview.scrollEnabled = YES;
searchTextValue = searchText;
[searchResult removeAllObjects];
for (NSString *str in ContactArray)
{
NSRange range = [str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(range.location != NSNotFound)
{
if(range.length > 0)//that is we are checking only the start of the names.
{
[searchResult addObject:str];
}
}
}
}
else
{
//---nothing to search---
isSearchOn = NO;
canSelectRow = NO;
self.ContactTableview.scrollEnabled = YES;
//SearchBar.showsCancelButton = NO;
[TitleBarLabel setText:#"All Contacts"];
}
[ContactTableview reloadData];
}
try with predicates,in below code replace your values.
NSPredicate *p = [NSPredicate predicateWithFormat:#"SELF BEGINSWITH[cd] %#",#"A"];
NSArray *a = [NSArray arrayWithObjects:#"AhfjA ", #"test1", #"Test", #"AntA", nil];
NSArray *b = [a filteredArrayUsingPredicate:p];
NSLog(#"--%#",b);
O/P:-
(
AntA,
AntA
)
I want to do the customized autocompletion for UITextView...
For example:
If the user starts to type "Busines" I would like to suggest "Business1", "Business2", , so that the user can select any one of the 2 suggestions or choose to type a new one.
All the custom word suggestion will be in the array...
How can I achieve this ??
Is completionsForPartialWordRange:inString:language: something that I can use.. How can I pass the values in the array???
You can try this code.
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring
{
[autocomplete_array removeAllObjects];
for(int i=0;i<[your_main_array count];i++)
{
NSString *curString = [your_main_array objectAtIndex:i];
curString = [curString lowercaseString];
substring = [substring lowercaseString];
if ([curString rangeOfString:substring].location == NSNotFound)
{}
else
{
[autocomplete_array addObject:curString]
}
}
[autocompletedisplayTableView reloadData];
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if( textView == your_TextView)
{
[your_TextView resignFirstResponder];
autocompletedisplayTableView.hidden = NO;
NSString *substring = [NSString stringWithString:your_TextView.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
}
your_main_array : will be your original array which you'll load from web service.
autocomplete_array : will be the array you'll get after the searching process is finished.
When user search you'll have to pass autocomplete_array to your UITableView
I am implementing a search bar controller to search a table view. The below method code which performs the search is crashing with the error "-[__NSArrayM rangeOfString:options:]: unrecognized selector sent to instance 0x65558e0'
The locationInfo array is an array containing 26 arrays, each of which contains a number of objects made up of strings.
Can anyone suggest why the code is crashing ?
Thank you.
- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release], array = nil;
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSString *currentString in [self locationInfo])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
}
}
}
}
As you stated in question that "locationInfo" is array containing 26 arrays,
so,
currentString in [self locationInfo] will return an array only so try to write something like below :
for (NSArray *currentArray in [self locationInfo])
{
for (NSString *currentString in currentArray)
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
}
}
}
or something like this
Based on the error you're getting, it seems [self locationInfo] returns an array (NSArray) and not a string (NSString) as you're expecting.
When using UISearchBar, the text "No Results" displayed in the searchResultsTableView, can we change the text "No Results" ?
In the first method, we are only changing the appearance of search bar when a user taps on search bar. Refer the first two images to find the difference. The main code will be written now:
take Label and set Text NO Resluts and Set Hidden YES In View DidLoad.
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[tableData removeAllObjects];
// remove all data that belongs to previous search
if([searchText isEqualToString:#""] || searchText==nil){
[tblview reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in dataSource)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
//NSRange r = [name rangeOfString:searchText];
NSRange r=[name rangeOfString:searchText options:NSCaseInsensitiveSearch];
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];
}
if([tableData count]==0)
{
label.hidden=NO;
}
[tblview reloadData];
}
I have a UIViewController (called AdjustViewController) that presents another UIViewController (called SourcePickerViewController) with a UIPickerView modally. I generate instances of the AdjustViewController and they in turn make a SourcePickerViewController. I make an NSDictionary and assign it and an integer to the AdjustViewController and it in turn sets the same properties in the SourcePickerController. This way I can reuse the controllers. The NSDictionary get set up in a UITableViewController that has all the AdjustViewControllers in it.
The problem comes when some of the pickers should have 1 component and some should have 2. The integer that I pass along is called numberOfComponents When I make a picker with numberOfComponents = 1 somehow it's changing to = 2 but I can't see how. I have NSLogs all over the place and I can see it happen as soon as the picker delegate method numberOfComponentsInPickerView is called. It's 1 right before and 2 right after.
There's obviously more code, but I think I have all the important parts. Although if that were true, maybe I'd know where the problem is!
Inside MenuViewController.m
- (void)viewDidLoad {
NSLog(#"ChemicalViewController launched");
self.title = #"Adjust Chemicals";
NSMutableArray *array = [[NSMutableArray alloc] init];
// Chlorine Controller
AdjustViewController *chlorineAdjustViewController = [[AdjustViewController alloc] initWithNibName:#"AdjustViewController" bundle:nil];
chlorineAdjustViewController.title = #"FC - Free Chlorine";
chlorineAdjustViewController.numberOfComponents = 2;
NSLog(#"Generating chlorine source dictionary");
NSDictionary *chlorineSourceDictionary = [self generateChlorineDictionary];
chlorineAdjustViewController.dictionaryOfSources = chlorineSourceDictionary;
[chlorineSourceDictionary release];
[array addObject:chlorineAdjustViewController];
[chlorineAdjustViewController release];
// CYA Controller
AdjustViewController *cyaAdjustViewController = [[AdjustViewController alloc] initWithNibName:#"AdjustViewController" bundle:nil];
cyaAdjustViewController.title = #"CYA - Cyanuric Acid";
cyaAdjustViewController.numberOfComponents = 1;
NSLog(#"Generating cya source dictionary");
NSDictionary *cyaSourceDictionary = [self generateCYADictionary];
cyaAdjustViewController.dictionaryOfSources = cyaSourceDictionary;
[cyaSourceDictionary release];
[array addObject:cyaAdjustViewController];
[cyaAdjustViewController release];
Inside AdjustViewController.m
// Present the picker for chlorine selection
- (IBAction)getChemicalSource {
SourcePickerViewController *sourcePickerViewController = [[SourcePickerViewController alloc] init];
sourcePickerViewController.delegate = self;
NSLog(#"getChemicalSource setting numberOfComponents %d", self.numberOfComponents);
sourcePickerViewController.numberOfComponents = self.numberOfComponents;
NSLog(#"getChemicalSource sending numberOfComponents %d", sourcePickerViewController.numberOfComponents);
sourcePickerViewController.dictionaryOfSources = self.dictionaryOfSources;
[self presentModalViewController:sourcePickerViewController animated:YES];
[sourcePickerViewController release];
}
#pragma mark -
#pragma mark Picker View Delegate Methods
// Returns the values from the picker if a source was chosen
- (void)sourcePickerViewController:(SourcePickerViewController *)controller
didSelectSource:(NSString *)source
andConcentration:(NSString *)concentration
andConstant:(float)constant
andIsLiquid:(BOOL)isLiquid {
sourceField.text = [[NSString alloc] initWithFormat:#"%#, %#", source, concentration];
[self updateAdvice];
NSLog(#"Returned source = %#, concentration = %#, sourceConstant = %1.7f, isLiquid = %d", source, concentration, constant, isLiquid);
[self dismissModalViewControllerAnimated:YES];
}
// Returns from the picker without choosing a new source
- (void)sourcePickerViewController:(SourcePickerViewController *)controller
didSelectCancel:(BOOL)didCancel {
[self updateAdvice];
NSLog(#"Returned without selecting source");
[self dismissModalViewControllerAnimated:YES];
}
Inside SourceViewController.m
- (void)viewDidLoad {
NSLog(#"SourcePickerViewController launched");
NSLog(#"viewDidLoad");
NSLog(#"Received numberOfComponents %d", self.numberOfComponents);
self.chemicalSources = dictionaryOfSources;
NSArray *components = [self.chemicalSources allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:#selector(compare:)];
self.sources = sorted; // This array has the chemical sources
if (self.numberOfComponents = 2) {
NSString *selectedSource = [self.sources objectAtIndex:0];
NSArray *chemArray = [self.chemicalSources objectForKey:selectedSource];
NSMutableArray *concentrationArray = [[NSMutableArray alloc] init];
int num = [chemArray count];
for (int i=0; i<num; i++) {
[concentrationArray addObject:[[chemArray objectAtIndex:i] chemConcentration]];
}
self.concentrations = concentrationArray;
}
[super viewDidLoad];
}
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
NSLog(#"numberOfComponentsInPickerView, self.numberOfComponents = %d", self.numberOfComponents);
return self.numberOfComponents;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
NSLog(#"numberOfRowsInComponent, self.numberOfComponents = %d", self.numberOfComponents);
if (component == kSourceComponent)
return [self.sources count];
return [self.concentrations count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (component == kSourceComponent)
return [self.sources objectAtIndex:row];
return [self.concentrations objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"didSelectRow, self.numberOfComponents = %d", self.numberOfComponents);
if (numberOfComponents = 2) {
if (component == kSourceComponent) {
NSString *selectedSource = [self.sources objectAtIndex:row];
NSArray *chemArray = [self.chemicalSources objectForKey:selectedSource];
NSMutableArray *concentrationArray = [[NSMutableArray alloc] init];
int num = [chemArray count];
for (int i=0; i<num; i++) {
[concentrationArray addObject:[[chemArray objectAtIndex:i] chemConcentration]];
}
self.concentrations = concentrationArray;
[picker selectRow:0 inComponent:kConcentrationComponent animated:YES];
[picker reloadComponent:kConcentrationComponent];
}
}
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
if (component == kConcentrationComponent)
return 90;
return 205;
}
I didn't look through all of your code; Instead, I'd recommend writing out the properties for numberOfComponents instead of #synthesize'ing them. Just get rid of your #synthesize, and make:
- (int)numberOfComponents {
return m_numberOfComponents;
}
and
- (void)setNumberOfComponents(int aNumberOfComponents) {
m_numberOfComponents = aNumberOfComponents;
}
Then, set a breakpoint in your setNumberOfComponents function, and you should be able to see whenever it's getting called, so you can see what is going on. I hope that helps!