I'm trying to get my contacts list in iOS to automatically add contacts to the contacts list without the user having to manually do it - similiar to how Whatsapp works. My code below simply shows prewritten values for the tableView and allows a bar button item to display the contacts list but not allow it to write any new entries to the tableView.
- (void)viewDidLoad
{
CFErrorRef *error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
for(int i = 0; i < numberOfPeople; i++) {
ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));
NSLog(#"Name:%# %#", firstName, lastName);
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
NSString *phoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
NSLog(#"phone:%#", phoneNumber);
}
}
self.friendsSearch.delegate = self;
self.friendsTableView.delegate = self;
self.friendsTableView.dataSource = self;
friendsListArray = [[NSMutableArray alloc] initWithObjects:
#"One",#"Two",#"Three",#"Four",#"Five",#"Six",#"Seven",#"Eight",#"Nine",#"Ten", #"Eleven", nil];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if(searchText.length == 0){
isFiltered = NO;
}
else
{
isFiltered = YES;
filterDataArray = [[NSMutableArray alloc]init];
for(NSString *str in friendsListArray){
NSRange stringRange = [str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (stringRange.location != NSNotFound){
[filterDataArray addObject:str];
}
}
}
[self.friendsTableView reloadData];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self.friendsSearch resignFirstResponder];
[self.view endEditing:YES];
}
// Table view datasource and delegate methods..
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(isFiltered){
return [filterDataArray count];
}
return [friendsListArray count];
return 1;
}
bool isKeyboardVisble = FALSE;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(!isFiltered){
cell.textLabel.text = [friendsListArray objectAtIndex:indexPath.row];
}
else //it is filtered
{
cell.textLabel.text = [filterDataArray objectAtIndex:indexPath.row];
}
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)backgroundClick:(id)sender {
[self.view endEditing:YES];
}
- (IBAction)addContact:(id)sender {
ABPeoplePickerNavigationController *peoplePicker =
[[ABPeoplePickerNavigationController alloc] init];
peoplePicker.peoplePickerDelegate = self;
[self presentModalViewController:peoplePicker animated:YES];
}
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)picker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
[self dismissModalViewControllerAnimated:YES];
return NO;
}
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)picker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
- (void)peoplePickerNavigationControllerDidCancel:
(ABPeoplePickerNavigationController *)picker
{
[self dismissModalViewControllerAnimated:YES];
}
#end
Related
I have a SearchBar on my tableView. It is correctly working when typing to search through the table view. However, when the cancel button is pressed, the tableView is not reloading the data.
-(void)viewDidLoad {
[super viewDidLoad];
isFiltered = false;
self.searchController = [[UISearchController alloc]
initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.tableView.tableHeaderView = self.searchController.searchBar;
self.definesPresentationContext = YES;
[self.searchController.searchBar sizeToFit];
}
- (void)viewWillAppear:(BOOL)animated {
NSBundle *bundle = [NSBundle mainBundle];
self.files = [bundle pathsForResourcesOfType:#"pdf" inDirectory:#"thepdfpowerpoints"];
NSString *documentsDirectoryPath = [self.files objectAtIndex:thepath.row];
self.title = #"Devo Songs";
self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
for (NSString *path in self.files) {
[names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
}
//self.files = names;
self.files = [names sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSLog(#"FILESLOAD%#", self.files);
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
-(void) updateSearchResultsForSearchController:(UISearchController *)searchController {
isFiltered = true;
NSString *searchText = self.searchController.searchBar.text;
searchResults = [[NSMutableArray alloc] init];
for (NSString *file in self.files) {
NSRange nameRange = [file rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (nameRange.location != NSNotFound) {
[searchResults addObject:file];
}
}
[self.tableView reloadData];
}
-(void) searchBarCancelButtonClicked:(UISearchBar *)searchBar {
//self.tableView.tableHeaderView = searchBar;
NSLog(#"Cancel");
isFiltered=false;
[self.tableView reloadData];
}
I have added an NSLog in cellForRowAtIndexPath This is showing in console when I first go to the view, but it is not being called when I click the cancel button.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Loading");
The code for number of rows/section is:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
if (isFiltered) {
return [searchResults count];
}
else {
return [self.files count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return 1;
}
Tapping the search bar's "Cancel" button clears the search text...
and then calls updateSearchResultsForSearchController.
So your current code is setting isFiltered to true again, and then reloading the table view based on an empty searchResults array.
You don't really need to implement searchBarCancelButtonClicked unless you want to do something other than refresh your table view.
Try changing your updateSearchResultsForSearchController method to this - it will use the full files array if no text has been entered in the search field. Otherwise, it will filter the files array.
-(void) updateSearchResultsForSearchController:(UISearchController *)searchController {
NSLog(#"update"); // just to show when this is being called
NSString *searchText = self.searchController.searchBar.text;
if (searchText.length != 0) {
isFiltered = YES;
searchResults = [[NSMutableArray alloc] init];
for (NSString *file in self.files) {
NSRange nameRange = [file rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (nameRange.location != NSNotFound) {
[searchResults addObject:file];
}
}
} else {
isFiltered = NO;
}
[self.tableView reloadData];
}
I have UITableView with countries and their phone codes
- (NSArray *)sortedCountryLetters {
if (_sortedCountryLetters == nil) {
[self countriesInfo];
}
return _sortedCountryLetters;
}
- (NSDictionary *)countriesInfo {
if (_countriesInfo == nil) {
NSMutableArray *countries = [NSMutableArray new];
for (NSString *key in [AppDelegate phoneCodes]) {
[countries addObject:#{
#"key": key,
#"name": [_locale displayNameForKey:NSLocaleCountryCode value:key],
#"code": [AppDelegate phoneCodes][key]
}];
}
NSMutableArray *firstLetters = [NSMutableArray new];
NSMutableDictionary *result = [NSMutableDictionary new];
for (NSDictionary *country in countries) {
NSString *name = country[#"name"];
NSString *firstLetter = [[name substringToIndex:1] uppercaseString];
if ([[result allKeys] containsObject:firstLetter]) {
NSMutableArray *letterCountries = result[firstLetter];
[letterCountries addObject:country];
}
else {
result[firstLetter] = [#[country] mutableCopy];
[firstLetters addObject:firstLetter];
}
}
[firstLetters sortUsingComparator:^NSComparisonResult(NSString *letter1, NSString *letter2) {
return [letter1 compare:letter2];
}];
_sortedCountryLetters = [firstLetters copy];
for (NSString *firstLetter in [result allKeys]) {
NSMutableArray *letterCountries = result[firstLetter];
[letterCountries sortUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
NSString *name1 = obj1[#"name"];
NSString *name2 = obj2[#"name"];
return [[name1 lowercaseString] compare:[name2 lowercaseString]];
}];
}
_countriesInfo = [result copy];
}
return _countriesInfo;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[[self countriesInfo] allKeys] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *firstLetter = [self sortedCountryLetters][section];
NSArray *letterCountries = [self countriesInfo][firstLetter];
return [letterCountries count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"countryCell"];
NSString *firstLetter = [self sortedCountryLetters][indexPath.section];
NSArray *letterCountries = [self countriesInfo][firstLetter];
NSDictionary *country = letterCountries[indexPath.row];
[[cell textLabel] setText:country[#"name"]];
[[cell textLabel] setTextColor:[OmwThemes defaultColorForegroundMain]];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [self sortedCountryLetters][section];
}
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [self sortedCountryLetters];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index] atScrollPosition:UITableViewScrollPositionTop animated:YES];
return [[self sortedCountryLetters] indexOfObject:title];
}
Section indices already shows at table view right side, but tapping do nothing.
In debug I saw that tableView:sectionForSectionIndexTitle:atIndex: method never called.
Table view is connected to datasource and delegate. I did try both plain and group table view styles.
What did I miss?
Update:
My table view look:
I want to create program that will import contacts from adressbook and show them in tableview. I already did code to download contacts from adressbook but when I'm adding them into Array and then trying to show in TableView they don't appear when I'm starting app. Here's code:
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[self getPersonOutOfAddressBook];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
Person *person = [self.tableData objectAtIndex:indexPath.row];
cell.textLabel.text = person.fullName;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)getPersonOutOfAddressBook
{
//1
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // We are on iOS 6
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(semaphore);
});
}
if (addressBook != nil) {
NSLog(#"Succesful.");
//2
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
//3
NSUInteger i = 0; for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
//4
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson,
kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
person.firstName = firstName; person.lastName = lastName;
person.fullName = fullName;
[self.tableData addObject:person];
}
//8
CFRelease(addressBook);
} else {
//9
NSLog(#"Error reading Address Book");
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
When I'm using debugger it shows that variables firstname, lastname and then fullname have access to adressbook because I can see name or last name of person. But I think there is problem with adding to array because I can't see anything in this array. Could someone help me? I'm beginner with Objective - C so please forbearance :)
To use an array you need to both declare it and create it. You do this by allocating and initializing the array.
self.tableData = [[NSMutableArray alloc] init];
I want to store address book of iOS in array and display that in UITableView. This is the code I am using. I just want contact name and phone number to be displayed.
pragma mark- address book methods
(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
ABPeoplePickerNavigationController *picker= [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentModalViewController:picker animated:YES];
return NO;
}
(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person{
ABMultiValueRef phone = (ABMultiValueRef) ABRecordCopyValue(person, kABPersonPhoneProperty);
ABMultiValueRef personID = (ABMultiValueRef) ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef phoneID = ABMultiValueCopyValueAtIndex(phone, 0);
//CFStringRef personName= ABMultiValueCopyValueAtIndex(personID, 0);
NSLog(#"%#",[NSString stringWithFormat:#"%#", phoneID]);
NSLog(#"%#",[NSString stringWithFormat:#"%#", personID]);
}
Please refer to Rays addressbook tutorial. I think it should answer all your questions.
Why are u calling the picker navigator on beginning of a text? You should call it through a button added as a right bar button item. Then select the persons you want and store them in a mutable array. After that dismiss the controller and load the table view.
Edited:
Please find the code below for your reference. I hope it might help in understanding how it is working. Here is the reference link to the sample code as well.
Interface:
#import <UIKit/UIKit.h>
#interface JSViewController : UITableViewController
#end
Implementation:
#import "JSViewController.h"
#import <AddressBookUI/AddressBookUI.h>
#import <AddressBook/AddressBook.h>
#interface JSViewController ()<ABPeoplePickerNavigationControllerDelegate,UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, strong) NSMutableArray *peopleSelected;
#end
#implementation JSViewController
-(NSMutableArray *)peopleSelected
{
if (!_peopleSelected) {
_peopleSelected = [NSMutableArray new];
}
return _peopleSelected;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIBarButtonItem *selectPerson = [[UIBarButtonItem alloc] initWithTitle:#"Select" style:UIBarButtonItemStyleBordered target:self action:#selector(btnSelectHandler:)];
self.navigationItem.rightBarButtonItem = selectPerson;
}
- (void)btnSelectHandler:(id)sender
{
ABPeoplePickerNavigationController *peoplePicker = [ABPeoplePickerNavigationController new];
peoplePicker.peoplePickerDelegate = self;
[self.navigationController presentViewController:peoplePicker animated:YES completion:^{
}];
}
#pragma mark - ABPeoplePickerNavigationControllerDelegate
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;
{
[self dismissViewControllerAnimated:YES completion:^{
if (self.peopleSelected) {
[self.tableView reloadData];
}
}];
}
The below method is deprecated in iOS 8.0. You can use the function
- peoplePickerNavigationController:didSelectPerson:
instead of this:
//Deprecated in iOS 8.0.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
NSString *name = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
ABMultiValueRef phoneNumbers = (ABRecordCopyValue(person, kABPersonPhoneProperty));
NSString *mobile = #"";
NSString *label = #"";
for (CFIndex i=0 ; i<ABMultiValueGetCount(phoneNumbers); i++) {
label = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(phoneNumbers, i);
if ([label isEqualToString:(NSString *)kABPersonPhoneMobileLabel]) {
mobile = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, i);
}else if([label isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel]){
mobile = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, i);
break;
}
}
NSDictionary *dict = #{#"name":name,
#"phone":mobile};
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.phone == %# && self.name == %#",mobile,name];
NSArray *personAlready = [self.peopleSelected filteredArrayUsingPredicate:predicate];
NSLog(#"personAlready %#",personAlready);
if (!personAlready.count) {
[self.peopleSelected addObject:dict];
}
return NO;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return YES;
}
#pragma mark - UITableViewDataSource
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.peopleSelected.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSDictionary *dict = self.peopleSelected[indexPath.row];
cell.textLabel.text = dict[#"name"];
return cell;
}
#pragma mark - UITableViewDelegate
#end
When i click search it executes a search class and after finding the results it executes numberOfRows method but then it is showing empty table. It is not executing cellForRowAtIndexPath method .
check my below code
code in viewcontroller.h
when i click search button this method will get executed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
SearchResultsViewController *searchRes=[[SearchResultsViewController alloc]initWithNibName:#"SearchResultsViewController" bundle:nil];
NSString *searchQuery=[search text];
sharedManager=[Mymanager sharedManager];
sharedManager.searchQuery=searchQuery;
[searchRes searchString:searchQuery];
[self.navigationController pushViewController:searchRes animated:YES];
}
in search class
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"%#",results);
return [results count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.adjustsFontSizeToFitWidth = YES;
NSLog(#"indexpath%d",indexPath.row);
NSLog(#"%#",[results objectAtIndex:[indexPath row]]);
SearchResult* hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
NSLog(#"%#",hit.neighboringText);
cell.textLabel.text = [NSString stringWithFormat:#"...%#...", hit.neighboringText];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Chapter %d - page %d", hit.chapterIndex, hit.pageIndex+1];
cell.textLabel.font = [UIFont fontWithName:#"Trebuchet MS" size:12];
cell.textLabel.textColor = [UIColor colorWithRed:25/255.0 green:90/255.0 blue:100/255.0 alpha:1];
// else
// {
//
// }
// [[self resultsTableView] reloadData];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
SearchResult* hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
[fvc loadSpine:hit.chapterIndex atPageIndex:hit.pageIndex highlightSearchResult:hit];
}
- (void) searchString:(NSString*)query{
// if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// {
self.results = [[NSMutableArray alloc] init];
[resultsTableView reloadData];
currentQuery=sharedManager.searchQuery;
//
[self searchString:currentQuery inChapterAtIndex:0];
//
// }else {
// currentQuery=sharedManager.searchQuery;
// [self searchString:currentQuery inChapterAtIndex:0];
//}
}
- (void) searchString:(NSString *)query inChapterAtIndex:(int)index{
currentChapterIndex = index;
sharedManager=[Mymanager sharedManager];
Chapter* chapter = [sharedManager.spineArray objectAtIndex:index];
NSLog(#"%d",chapter.text.length);
NSRange range = NSMakeRange(0, chapter.text.length);
NSLog(#"%#",sharedManager.searchQuery);
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
int hitCount=0;
while (range.location != NSNotFound) {
range = NSMakeRange(range.location+range.length, chapter.text.length-(range.location+range.length));
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
hitCount++;
}
if(hitCount!=0){
UIWebView* webView = [[UIWebView alloc] initWithFrame:chapter.windowSize];
[webView setDelegate:self];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:chapter.spinePath]];
[webView loadRequest:urlRequest];
} else {
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching = NO;
}
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
NSLog(#"%#", error);
[webView release];
}
- (void) webViewDidFinishLoad:(UIWebView*)webView{
NSString *varMySheet = #"var mySheet = document.styleSheets[0];";
NSString *addCSSRule = #"function addCSSRule(selector, newRule) {"
"if (mySheet.addRule) {"
"mySheet.addRule(selector, newRule);" // For Internet Explorer
"} else {"
"ruleIndex = mySheet.cssRules.length;"
"mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex);" // For Firefox, Chrome, etc.
"}"
"}";
NSString *insertRule1 = [NSString stringWithFormat:#"addCSSRule('html', 'padding: 0px; height: %fpx; -webkit-column-gap: 0px; -webkit-column-width: %fpx;')", webView.frame.size.height, webView.frame.size.width];
NSString *insertRule2 = [NSString stringWithFormat:#"addCSSRule('p', 'text-align: justify;')"];
NSString *setTextSizeRule = [NSString stringWithFormat:#"addCSSRule('body', '-webkit-text-size-adjust: %d%%;')",[[sharedManager.spineArray objectAtIndex:currentChapterIndex] fontPercentSize]];
[webView stringByEvaluatingJavaScriptFromString:varMySheet];
[webView stringByEvaluatingJavaScriptFromString:addCSSRule];
[webView stringByEvaluatingJavaScriptFromString:insertRule1];
[webView stringByEvaluatingJavaScriptFromString:insertRule2];
[webView stringByEvaluatingJavaScriptFromString:setTextSizeRule];
[webView highlightAllOccurencesOfString:sharedManager.searchQuery];
NSString* foundHits = [webView stringByEvaluatingJavaScriptFromString:#"results"];
NSLog(#"%#", foundHits);
NSMutableArray* objects = [[NSMutableArray alloc] init];
NSArray* stringObjects = [foundHits componentsSeparatedByString:#";"];
for(int i=0; i<[stringObjects count]; i++){
NSArray* strObj = [[stringObjects objectAtIndex:i] componentsSeparatedByString:#","];
if([strObj count]==3){
[objects addObject:strObj];
}
}
NSArray* orderedRes = [objects sortedArrayUsingComparator:^(id obj1, id obj2){
int x1 = [[obj1 objectAtIndex:0] intValue];
int x2 = [[obj2 objectAtIndex:0] intValue];
int y1 = [[obj1 objectAtIndex:1] intValue];
int y2 = [[obj2 objectAtIndex:1] intValue];
if(y1<y2){
return NSOrderedAscending;
} else if(y1>y2){
return NSOrderedDescending;
} else {
if(x1<x2){
return NSOrderedAscending;
} else if (x1>x2){
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
}];
[objects release];
NSLog(#"%#",currentQuery);
for(int i=0; i<[orderedRes count]; i++){
NSArray* currObj = [orderedRes objectAtIndex:i];
SearchResult* searchRes = [[SearchResult alloc] initWithChapterIndex:currentChapterIndex pageIndex:([[currObj objectAtIndex:1] intValue]/webView.bounds.size.height) hitIndex:0 neighboringText:[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"unescape('%#')", [currObj objectAtIndex:2]]] originatingQuery:currentQuery];
[results addObject:searchRes];
NSLog(#"%#",results);
[searchRes release];
}
//Print results
for(int i=0;i<[results count];i++)
{
SearchResult* hit = (SearchResult*)[results objectAtIndex:i];
NSLog(#"%#",hit.neighboringText);
}
[resultsTableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching= NO;
}
[[self resultsTableView] reloadData];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
//- (void)dealloc
////{
//// self.resultsTableView = nil;
//// //[results release];
//// //[currentQuery release];
//// [super dealloc];
//}
- (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];
resultsTableView=[[UITableView alloc]init];
[resultsTableView setDelegate:self];
[resultsTableView setDataSource:self];
sharedManager=[Mymanager sharedManager];
// Do any additional setup after loading the view from its nib.
results = [[NSMutableArray alloc] init];
self.navigationItem.title=#"Search ";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem=backButton;
[[UINavigationBar appearance] setTitleTextAttributes: #{
UITextAttributeTextColor: [UIColor whiteColor],
UITextAttributeTextShadowColor: [UIColor lightGrayColor],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0.0f, 1.0f)],
UITextAttributeFont: [UIFont fontWithName:#"Trebuchet MS" size:15.0f]
}];
noMatchingSearch=[[NSArray alloc]initWithObjects:#"No Element Found", nil];
tableOfContents=[[NSMutableArray alloc]init];
for (id img in search.subviews)
{
if ([img isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
[img removeFromSuperview];
}
}
tableOfContents=[sharedManager.List copy];
}
- (void)viewDidUnload
{
search = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
self.resultsTableView = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
MY SEARCH RESULTS
"<SearchResult: 0x113482c0>",
"<SearchResult: 0x11348a20>",
"<SearchResult: 0x88c0a50>"
The problem is with the search method before search the array is reinitialised and hence 0 returned in the resultArray and hence no value in tables
- (void) searchString:(NSString*)query{
self.results = [[NSMutableArray alloc] init];//Here it becomes 0!!
[resultsTableView reloadData];
currentQuery=sharedManager.searchQuery;
}
To make it right ,After the search is performed i believe
[self searchString:currentQuery inChapterAtIndex:0];
load the value in the result array and then reload table.
Make sure
in .h add
<UITableViewDataSource,UITableViewDelegate>
in nib
connect datasource and delegate[if via nib]