Textfields as search bar getting crash - ios

I am using this code for textfiled as search bar.Here is my code. but i am getting crash for range on textfield.if i start entering then its crashing.Even not able to handle case sensitive text also
#import "ViewController.h"
#import "AFNetworking.h"
#import <QuartzCore/QuartzCore.h>
#interface ViewController ()
{
NSMutableArray *countryArray;
NSMutableArray *searchArray;
NSString *searchTextString;
BOOL isFilter;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_countryView.hidden = true;
self->countryArray = [[NSMutableArray alloc] init];
[self makeRestuarantsRequests];
_tableView.layer.borderColor = [UIColor lightGrayColor].CGColor;
_tableView.layer.borderWidth = 1;
_tableView.layer.cornerRadius=5;
[self.searchTextField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}
-(void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter]removeObserver:self
name:UITextFieldTextDidChangeNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - AFNetworking
-(void)makeRestuarantsRequests{
NSURL *url = [NSURL URLWithString:#"example url"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id responseObject) {
self->countryArray = [responseObject objectForKey:#"data"];
[self.tableView reloadData];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id responseObject) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
}
#pragma mark - Tableview Delegate and Datasource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(isFilter)
{
return [searchArray count];
}
else
return [countryArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *tempDictionary= [self->countryArray objectAtIndex:indexPath.row];
if(isFilter)
{
cell.textLabel.text=[searchArray objectAtIndex:indexPath.row];
}
else
{
cell.textLabel.text = [tempDictionary objectForKey:#"name"];
}
// cell.textLabel.text = [tempDictionary objectForKey:#"name"];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[_SelectCountryButton setTitle:cell.textLabel.text forState:UIControlStateNormal];
_countryView.hidden = true;
}
-(void)textFieldDidChange:(UITextField *)textField
{
searchTextString=textField.text;
[self updateSearchArray:searchTextString];
}
-(void)updateSearchArray:(NSString *)searchText
{
if(searchText.length==0)
{
isFilter=NO;
}
else{
isFilter=YES;
searchArray=[[NSMutableArray alloc]init];
for(NSString *string in countryArray){
NSRange stringRange=[string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location !=NSNotFound){
[searchArray addObject:string];
}
}
[self.tableView reloadData];}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#pragma mark UITextFieldDelegates
- (IBAction)SelectCountry:(id)sender {
_countryView.hidden = false;
}
#end
Getting crash error :
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI rangeOfString:options:]: unrecognized selector sent to instance 0x10128b4f0
error code :
-(void)updateSearchArray:(NSString *)searchText
{
if(searchText.length==0)
{
isFilter=NO;
}
else{
isFilter=YES;
searchArray=[[NSMutableArray alloc]init];
for(NSString *string in countryArray){
NSRange stringRange=[string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location !=NSNotFound){
[searchArray addObject:string];
}
}
[self.tableView reloadData];}
}
Please help me out.How can i solve this issues.
Thanks in advance !
UPDATE :
{"response":true,"message":"country.","data":[{"id":1,"name":"Afghanistan"},{"id":2,"name":"Albania"},{"id":3,"name":"Algeria"},{"id":4,"name":"American Samoa"},{"id":5,"name":"Andorra"},{"id":6,"name":"Angola"}]}

well i have good approach with predicate
well according to you jsonResponse
// so forEach loop should like this
for(NSDictionary *Dic in CountryArray){
NSString*str=[NSString stringWithFormat:#"%#",[dic objectForKey:#"name"]];
}
// well i am not using for each loop instead of that i have nsmutablearray name as _searchArraySingle is same like your countryArray with predicate
// if you are using textfield in place of default Searchbar so use this then use NSPredicate
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(textFieldTextDidChangeOneCI:)
name:UITextFieldTextDidChangeNotification
object:searchTxt];
SearchBar.delegate = (id)self;
}
-(void)textFieldTextDidChangeOneCI:(NSNotification *)notification {
UITextField *textfield=[notification object];
[self predicatChangeText:textfield.text];
// NSLog(#"%#",textfield.text);
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
-(void)predicatChangeText:(NSString*)text{
// myJSON.array
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"%K contains[cd] %#", #"name", text];
_filteredArray = [NSMutableArray arrayWithArray:[_searchArraySingle filteredArrayUsingPredicate:predicateString]];
NSLog(#"_filteredArray=%lu",(unsigned long)[_filteredArray count]);
[self.tableView reloadData];
}
- (IBAction)cancleSearch:(id)sender {
searchTxt.text=#"";
if (_filteredArray) {
_filteredArray=nil;
}
[self.searchTxt resignFirstResponder];
_filteredArray = myJSON.array;
[self.tableView reloadData];
}
Might this will help you out !!!! GoodLuck

Related

Obj-C - didSelectRowAtIndexPath not firing?

I'm stumped. For some reason, when I tap my tableView cell, didSelectRowAtIndexPath is not executing? And yes, my tableView delegate is set, and data is populated in the cell label. Am I missing something obvious from my below? Essentially, when my user taps the tableView cell, the contents of the cell label should appear in a textfield.
.h
#interface RegisterViewController : UIViewController <UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource, UIImagePickerControllerDelegate> {
}
#property (nonatomic) IBOutlet UITableView *tableView;
#end
.m
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.hidden = NO;
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
- (void)LoadJson_search{
searchArray=[[NSMutableArray alloc]init];
// NSLog(#"str......%#",strSearch);
// This API key is from https://developers.google.com/maps/web/
NSString *str1 = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input=%#&key=AIzaSyAm7buitimhMgE1dKV2j4_7doULluiiDzU", strSearch];
NSURL *url = [NSURL URLWithString:str1];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error=nil;
if(data.length==0)
{
}
else
{
NSDictionary *jsondic= [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
// NSLog(#"1,,,,%#",jsondic);
[searchArray removeAllObjects];
if([[jsondic objectForKey:#"status"]isEqualToString:#"ZERO_RESULTS"])
{
}
else if([[jsondic objectForKey:#"status"]isEqualToString:#"INVALID_REQUEST"])
{
}
else
{
for(int i=0;i<[jsondic.allKeys count];i++)
{
NSString *str1=[[[jsondic objectForKey:#"predictions"] objectAtIndex:i] objectForKey:#"description"];
[searchArray addObject:str1];
}
self.tableView.hidden = NO;
// NSLog(#"%#", searchArray);
}
if (searchArray.count == 0) {
self.tableView.hidden = YES;
}else{
[self.tableView reloadData];
}
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// if (self.addressField.tag == 3) {
if (textField == self.addressField) {
strSearch = [self.addressField.text stringByReplacingCharactersInRange:range withString:string];
if([string isEqualToString:#" "]){
}else{
[self LoadJson_search];
}}
// }
return YES;
}
- (BOOL)textFieldShouldClear:(UITextField *)textField{
self.tableView.hidden = YES;
[self.tableView reloadData];
return YES;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return searchArray.count;
}
-(UITableViewCell *)tableView:(UITableView*)aTableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"cell"];
if(!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.textLabel.text = [searchArray objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"TAPPED CELL");
self.addressField.text = [searchArray objectAtIndex:indexPath.row];
self.tableView.hidden = YES;
[self.tableView reloadData];
}
Try with the next line in your viewDidLoad:
self.tableView.allowsSelection = YES;
Or check that property in your storyboard. Well you can try with the cell too like this:
// This line do not affect the selection delegate only the style
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.userInteractionEnabled = YES;

How to Impliment Search bar in Table view for Contacts in ios [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
i have following code in viewdidload
totalstring=[[NSMutableArray alloc]initWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i",#"j",#"k",#"l",#"m",#"n",#"n",#"o",#"p",#"q",#"r",#"s",#"s",#"t",#"u",#"v",#"w",#"x",#"y",#"z", nil];
indid=indidvalue1;
NSLog(#"the ind id value is %#",indid);
serviceCall=[[Services alloc]init];
NSString *contactsDisplay1=#"ContactDetails";
NSDictionary *contactsDisplayDetails1 =#{#"IND_ID":indid};
[serviceCall ContactsDisplayUrl:contactsDisplay1 ContactsDisplayDetails:contactsDisplayDetails1];
[serviceCall setDelegate:self];
code for implimenting search bar
{
filteredstring =[[NSMutableArray alloc]init];
for (NSString *str in totalstring )
{
NSRange stringrange =[str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringrange.location!= NSNotFound)
{
[filteredstring addObject:str];
}
}
}
[tableView reloadData];
code for table view
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [searchResultsArray objectAtIndex:indexPath.row];
} else
{
UIFont *myfont=[UIFont fontWithName:#"Arial" size:35];
cell.textLabel.text = [contactNameSplitDisplayArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[relationTypeSplitDisplayArray objectAtIndex:indexPath.row];
cell.textLabel.font=myfont;
}
return cell;
How can i implement search bar in table view for contacts in story board ?I am new to iOS
?
and how to implement plus button and dots button within the table view?
Devi my complete answer.It works perfectly.I use search bar.Also use that delegate methods.
ViewController.h
#import <UIKit/UIKit.h>
#import <Contacts/Contacts.h> //Must import contact framework
#interface ViewController : UIViewController<UISearchBarDelegate,UITableViewDataSource,UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UISearchBar *searchbarContacts;
#property (strong, nonatomic) IBOutlet UITableView *tableViewContactData;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrayTableData;
NSMutableArray *arraySearchContactData;
}
#end
#implementation ViewController
#synthesize tableViewContactData;
#synthesize searchbarContacts;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrayTableData = [[NSMutableArray alloc]init];
arraySearchContactData = [[NSMutableArray alloc]init];
[self fetchContactsandAuthorization];
[tableViewContactData registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
[self.view addSubview:tableViewContactData];
}
//Fetching Contact and Authorization access
-(void)fetchContactsandAuthorization
{
// Request authorization to Contacts
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
NSString *phone;
NSString *fullName;
NSString *firstName;
NSString *lastName;
UIImage *profileImage;
NSMutableArray *contactNumbersArray = [[NSMutableArray alloc]init];
for (CNContact *contact in cnContacts)
{
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
if (lastName == nil) {
fullName=[NSString stringWithFormat:#"%#",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:#"%#",lastName];
}
else{
fullName=[NSString stringWithFormat:#"%# %#",firstName,lastName];
}
UIImage *image = [UIImage imageWithData:contact.imageData];
if (image != nil) {
profileImage = image;
}else{
profileImage = [UIImage imageNamed:#"person-icon.png"];
}
for (CNLabeledValue *label in contact.phoneNumbers)
{
phone = [label.value stringValue];
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
}
}
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys: fullName,#"fullName",profileImage,#"userImage",phone,#"PhoneNumbers", nil];
[arrayTableData addObject:[NSString stringWithFormat:#"%#",[personDict objectForKey:#"fullName"]]];
[arraySearchContactData addObject:[NSString stringWithFormat:#"%#",[personDict objectForKey:#"fullName"]]];
NSLog(#"The contactsArray are - %#",arrayTableData);
}
dispatch_async(dispatch_get_main_queue(), ^{
[tableViewContactData reloadData];
});
}
}
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableView Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrayTableData.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
cell.textLabel.text = arrayTableData[indexPath.row];
return cell;
}
#pragma mark - SearchBar Delegate Methods
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
#try
{
[arrayTableData removeAllObjects];
stringSearch = #"YES";
NSString *name = #"";
if ([searchText length] > 0)
{
for (int i = 0; i < [arraySearchContactData count] ; i++)
{
name = [arraySearchContactData objectAtIndex:i];
if (name.length >= searchText.length)
{
NSRange titleResultsRange = [name rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
{
[arrayTableData addObject:[arraySearchContactData objectAtIndex:i]];
}
}
}
}
else
{
[arrayTableData addObjectsFromArray:arraySearchContactData];
}
[tableViewContactData reloadData];
}
#catch (NSException *exception) {
}
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)SearchBar
{
SearchBar.showsCancelButton=YES;
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)theSearchBar
{
[theSearchBar resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)SearchBar
{
#try
{
SearchBar.showsCancelButton=NO;
[SearchBar resignFirstResponder];
[tableViewContactData reloadData];
}
#catch (NSException *exception) {
}
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)SearchBar
{
[SearchBar resignFirstResponder];
}
#end
The Printed results For Contacts
The contactsArray are - (
"John Appleseed",
"Kate Bell",
"Anna Haro",
"Daniel Higgins",
"David Taylor",
"Hank Zakroff"
)
Please Refer the below link, i can able to implement the search bar in table view by using this.
http://www.appcoda.com/search-bar-tutorial-ios7/

How to apply custom search on uitextfield for place search using gmsAutocomplete view controller.?

HI all i am working on GMSAutocompleteViewController in my app. i have a uitextfield in my view controller when i tapp textfield for search a place using google api, a new view is open which is powered by google. Look at my code please.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
tappedTextField = textField;
GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init];
acController.delegate = self;
[self presentViewController:acController animated:YES completion:nil];
}
- (void)viewController:(GMSAutocompleteViewController *)viewController
didAutocompleteWithPlace:(GMSPlace *)place {
// Do something with the selected place.
NSLog(#"Place name %#", place.name);
NSLog(#"Place address %#", place.formattedAddress);
NSLog(#"Place attributions %#", place.attributions.string);
NSLog(#"lat and log%f", place.coordinate.latitude);
NSLog(#"lang %f", place.coordinate.longitude);
tappedTextField.text = place.name;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewController:(GMSAutocompleteViewController *)viewController
didFailAutocompleteWithError:(NSError *)error {
// TODO: handle the error.
NSLog(#"error: %ld", (long)[error code]);
[self dismissViewControllerAnimated:YES completion:nil];
}
// User canceled the operation.
- (void)wasCancelled:(GMSAutocompleteViewController *)viewController {
NSLog(#"Autocomplete was cancelled.");
[self dismissViewControllerAnimated:YES completion:nil];
}
i don't want to move to another view on textfield tapp for searching. is it possible that i can search places from the textfield only?
when i click on destination textfield a new view is appear for searching but i need search from textfield only please at the screen after tapp the textfield.
It sounds like what you're after is to display the autocomplete results in a table immediately underneath the textfield when the text field is active (ie something similar to this).
You can do this by creating a UITableView that you display in your UI in the right location. Instead of using GMSAutocompleteViewController, create a GMSAutocompleteTableDataSource and set it as the UITableView's delegate and data source. For example:
_tableDataSource = [[GMSAutocompleteTableDataSource alloc] init];
_tableDataSource.delegate = self;
tableView.delegate = _tableDataSource;
tableView.dataSource = _tableDataSource;
When the text field text changes, call sourceTextHasChanged on the table data source.
[_tableDataSource sourceTextHasChanged:textField.text];
Finally, have the parent view controller implement the GMSAutocompleteTableDataSourceDelegate protocol
There is some example code in the sample app contained in the GoogleMaps CocoaPod that is close to what you want. Look for SDKDemoAutocompleteWithTextFieldController.m in the downloaded Pods directory.
I used this code to achieve same behaviour you are asking.
-(void)LoadJson_search{
searchArray=[[NSMutableArray alloc]init];
NSLog(#"str......%#",strSearch);
NSString *str1 = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%#&key=AIzaSyD2NttUhPQ4PKvpju97qpeWj8SYnZtzt0s",strSearch];
NSLog(#"%#",strSearch);
NSURL *url = [NSURL URLWithString:str1];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error=nil;
if(data.length==0)
{
}
else
{
NSDictionary *jsondic= [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
// NSLog(#"1,,,,%#",jsondic);
[searchArray removeAllObjects];
if([[jsondic objectForKey:#"status"]isEqualToString:#"ZERO_RESULTS"])
{
}
else if([[jsondic objectForKey:#"status"]isEqualToString:#"INVALID_REQUEST"])
{
}
else
{
for(int i=0;i<[jsondic.allKeys count];i++)
{
//['predictions'][0]['description']
NSString *str1=[[[jsondic objectForKey:#"predictions"] objectAtIndex:i] objectForKey:#"description"];
[searchArray addObject:str1];
}
tbl_vw1.hidden=FALSE;
}
if (searchArray.count == 0) {
tbl_vw1.hidden = TRUE;
}
else{
[tbl_vw1 reloadData];
}
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;{
if (textField.tag == 3) {
strSearch = [textField.text stringByReplacingCharactersInRange:range withString:string];
if([string isEqualToString:#" "]){
}
else{
[self LoadJson_search];
}
}
return YES;
}
And on tableview didSelect method use following
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
strSelectedAddress = [searchArray objectAtIndex:indexPath.row];
[self.eventDict setObject:strSelectedAddress forKey:#"venue"];
//[self geoCodeUsingAddress:str_select_address];
tbl_vw1.hidden=TRUE;
[tbl_vw reloadData];
}
after reloading table, use this in cellForRowAtIndexpath to update selected place name.
cell.txt.text = [self.eventDict objectForKey:#"venue"];
Hope this helps you. :)
This is my answer based on # Nij. This will give complete satisfaction you to ...
#import "ViewController.h"
#import <GooglePlaces/GooglePlaces.h>
#interface ViewController () <UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *searchArray;
NSString *strSearch;
}
#property (weak, nonatomic) IBOutlet UITextField *searchTextfeild;
#property (weak, nonatomic) IBOutlet UITableView *tbl_vw1;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_searchTextfeild.delegate = self;
_tbl_vw1.delegate = self;
_tbl_vw1.dataSource = self;
_tbl_vw1.hidden = YES;
_searchTextfeild.clearButtonMode = UITextFieldViewModeAlways;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)LoadJson_search{
searchArray=[[NSMutableArray alloc]init];
// NSLog(#"str......%#",strSearch);
// This API key is from https://developers.google.com/maps/web/
NSString *str1 = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input=%#&key=AIzaSyAm7buitimhMgE1dKV2j4_7doULluiiDzU", strSearch];
NSURL *url = [NSURL URLWithString:str1];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error=nil;
if(data.length==0)
{
}
else
{
NSDictionary *jsondic= [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
// NSLog(#"1,,,,%#",jsondic);
[searchArray removeAllObjects];
if([[jsondic objectForKey:#"status"]isEqualToString:#"ZERO_RESULTS"])
{
}
else if([[jsondic objectForKey:#"status"]isEqualToString:#"INVALID_REQUEST"])
{
}
else
{
for(int i=0;i<[jsondic.allKeys count];i++)
{
NSString *str1=[[[jsondic objectForKey:#"predictions"] objectAtIndex:i] objectForKey:#"description"];
[searchArray addObject:str1];
}
_tbl_vw1.hidden = NO;
// NSLog(#"%#", searchArray);
}
if (searchArray.count == 0) {
_tbl_vw1.hidden = YES;
}else{
[_tbl_vw1 reloadData];
}
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;{
if (textField.tag == 3) {
strSearch = [textField.text stringByReplacingCharactersInRange:range withString:string];
if([string isEqualToString:#" "]){
}else{
[self LoadJson_search];
}
}
return YES;
}
- (BOOL)textFieldShouldClear:(UITextField *)textField{
_tbl_vw1.hidden = YES;
[_tbl_vw1 reloadData];
return YES;
}
//TableView delegates
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return searchArray.count;
}
-(UITableViewCell *)tableView:(UITableView*)aTableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
UITableViewCell *cell = [_tbl_vw1 dequeueReusableCellWithIdentifier:#"cell"];
if(!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
// NSLog(#"searchArray ==== %#", searchArray);
cell.textLabel.text = [searchArray objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
_searchTextfeild.text = [searchArray objectAtIndex:indexPath.row];
_tbl_vw1.hidden = YES;
[_tbl_vw1 reloadData];
}

Nothing shows in custom headerView

When I run the application, the header view container space is there, and is visible. I'm trying to display the username inside the header view, but nothing is showing up. Here is my code so far in the tableView:
#import "HomeView.h"
#interface HomeView () <UIActionSheetDelegate, UIImagePickerControllerDelegate>
#end
#implementation HomeView
- (void)viewDidLoad {
[super viewDidLoad];
if ([PFUser currentUser]) {
NSLog(#"Welcome to the App, %#", [self.user objectForKey:#"username"]);
} else {
LoginView *loginView = [[LoginView alloc] init];
[loginView setHidesBottomBarWhenPushed:YES];
[loginView.navigationItem setHidesBackButton:YES];
[self.navigationController pushViewController:loginView animated:NO];
}
UIBarButtonItem *takePhoto = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:#selector(takePhoto:)];
self.navigationItem.rightBarButtonItem = takePhoto;
// [self.tableView registerClass:[HomeViewCell class] forCellReuseIdentifier:#"cellIdentifier"];
// [self.tableView registerNib:[UINib nibWithNibName:#"HomeViewCell" bundle:nil]
// forCellReuseIdentifier:#"cellIdentifier"];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
self.reusableSectionHeaderViews = [NSMutableSet setWithCapacity:3];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
PFQuery *query = [PFQuery queryWithClassName:#"UserPhotos"];
[query orderByDescending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
} else {
self.userPhotos = objects;
NSLog(#"Retrieved objects: %#", self.userPhotos);
[self.tableView reloadData];
}
}];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger sections = self.userPhotos.count;
// Return the number of sections.
return sections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return 1;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (section == self.userPhotos.count) {
// Load More section
return nil;
}
HomeHeaderView *headerView = [self dequeueReusableSectionHeaderView];
if (!headerView) {
headerView = [[HomeHeaderView alloc] initWithFrame:CGRectMake( 0.0f, 0.0f, self.view.bounds.size.width, 44.0f) buttons:HomePhotoHeaderButtonsDefault];
headerView.delegate = self;
[self.reusableSectionHeaderViews addObject:headerView];
}
//Setting the username display.
PFObject *owner = [self.userPhotos objectAtIndex:section];
PFUser *user = [owner objectForKey:#"user"];
[user fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
NSString *username = user.username;
[headerView.userButton setTitle:username forState:UIControlStateNormal];
}
}];
return headerView;
}
- (HomeHeaderView *)dequeueReusableSectionHeaderView {
for (HomeHeaderView *sectionHeaderView in self.reusableSectionHeaderViews) {
if (!sectionHeaderView.superview) {
// we found a section header that is no longer visible
return sectionHeaderView;
}
}
return nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cellIdentifier";
HomeViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[HomeViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Setting the image in the cell.
PFObject *carPhoto = [self.userPhotos objectAtIndex:indexPath.row];
PFFile *imageFile = [carPhoto objectForKey:#"imageFile"];
NSURL *imageFileUrl = [[NSURL alloc] initWithString:imageFile.url];
NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
cell.carImage.contentMode = UIViewContentModeScaleAspectFit;
cell.carImage.image = [UIImage imageWithData:imageData];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 269;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == self.userPhotos.count) {
return 0.0f;
}
return 44.0f;
}
[user fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
NSString *username = user.username;
[headerView.userButton setTitle:username forState:UIControlStateNormal];
}
}];
The code above, you are updating the headerview UI from a background thread. You need to wrap the UI part so it performs on the main thread.
dispatch_async(dispatch_get_main_queue(), ^{
[headerView.userButton setTitle:username forState:UIControlStateNormal];
};
You need to be careful though, you are performing a background operation and then updating the header which you are reusing. There is a chance that the header is reused for a new section before the operation finishes and it is then set with the wrong username for that section. You can take care of this by not reusing the header or canceling the network operation if the header scrolls off screen before the operation finishes.

Indexed Search similar to the Facebook/Google search engine

Indexed search in a UIViewController! At any letters inserted into the textfield research, a method is called that executes a database query to obtain tuples as a function of string.
If I write a letter after letter, the app crashes because the method is called again while it is still running.
Instead, if I write a letter, look forward to the completion of the dispatch queue and write another letter, everything works! But I would like to perform as described in the first case!
Here the code:
- (IBAction)searchUser:(id)sender{
dispatch_async(dispatch_get_main_queue(), ^{
[_arrID removeAllObjects];
[_arrNames removeAllObjects];
[_arrPictures removeAllObjects];
[self.tableView reloadData];
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
CGRect activityFrame = CGRectMake(self.view.center.x, self.view.center.y, 0.0, 0.0);
_activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:activityFrame];
[[self.view superview] addSubview:_activityIndicator];
_activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
_activityIndicator.color = [UIColor whiteColor];
[_activityIndicator startAnimating];
});
//Here I fill the 3 arrays with details obtained from external queries on database
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
[_activityIndicator stopAnimating];
});
});
}
}
Is there a solution to conduct research in a manner similar to the facebook/google search engine? Given that I don't use UISearchDisplayController, but I just use a textfield that calls the method searchUser every [Editing Did Change] and it filled the Tableview with all results! Please help me!
in your .h file declare the array name
#interface newactivecomposeViewController : UIViewController<
UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate>
{
BOOL SelectionAvailable;
}
#property (strong, nonatomic) NSMutableArray *AllDetails,*SuggestionArray;
#property (strong, nonatomic) UITableView *tablevie;
in your .m file
#synthesize SuggestionArray,AllDetails,tablevie;
- (void)viewDidLoad
{
SuggestionArray=[[NSMutableArray alloc]init]; //for using the searching
self.AllDetails=[[NSMutableArray alloc] init]; //store the all name in this array
tablevie=[[UITableView alloc]initWithFrame:CGRectMake(23, 136, 277, 214)]; //tableview created dynamically
tablevie.dataSource=self;
tablevie.delegate=self;
[self.tablevie registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
[self.view addSubview:tablevie];
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {
[SuggestionArray removeAllObjects];
for (NSDictionary *tmp in self.AllDetails) {
NSRange substringRange =[[[tmp objectForKey:#"name"] lowercaseString] rangeOfString:[substring lowercaseString]];
if (substringRange.location==0) {
[SuggestionArray addObject:tmp];
}
}
if ([SuggestionArray count]==0) {
tablevie.hidden=YES;
}
else {
tablevie.hidden=NO;
}
[tablevie reloadData];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
for (NSString *tmp in getfrinendname) {
NSLog(#"%#", tmp);
if ([[textField.text lowercaseString] isEqualToString:[tmp lowercaseString]]) {
textField.text=tmp;
SelectionAvailable=YES;
break;
}
else {
SelectionAvailable=NO;
}
}
if (!SelectionAvailable) {
if (textField.text.length==0)
{
textField.text=#"";
}
// else if (textField.text.length >0)
// {
//
// [textField resignFirstResponder];
// [tablevie setHidden:YES];
//
// }
else
{
Alert=[[UIAlertView alloc]initWithTitle:#"User not found!" message:#"Please try again" delegate:Nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[Alert show];
}
}
#pragma tablevie data source
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"the count==%lu",(unsigned long)[SuggestionArray count]);
return [SuggestionArray 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=[[SuggestionArray objectAtIndex:indexPath.row] objectForKey:#"name"]; //load your key or index
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
yourtextfieldname.text=[NSString stringWithFormat:#"%#",[[SuggestionArray objectAtIndex:indexPath.row] objectForKey:#"name"]];
}

Resources