Search bar for searching in article in iOS - iphone

Hello there, I'm new iphone developer and I want you guidance…
I want to make an app with legal terms and explanation to different legal articles…
The problem is that I want to have a search bar, so the user is able to search inside the article for any word that he wants…how can this be done???
Thanks

I have array of dictionary and i am searching record like this
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
ProductFilteredArray = [[NSMutableArray alloc] init];
for (NSMutableDictionary * cty in globleAry)
{
NSRange nameRange = [[cty objectForKey:#"Name"] rangeOfString:text options:NSCaseInsensitiveSearch];
if(nameRange.location != NSNotFound)
{
[ProductFilteredArray addObject:cty];
}
}
//copy this array in arrat of table
tableArray = [ProductFilteredArray mutableCopy];
[table reloadData];
}

Related

UISearchBar Scope Bar Method

I have a UISearchBar in my app.and I want the four Scope bars in this UISearchBar that I have given from the XIB file .say one , two , three and four and now Problem is I have four array s which contains separates values for each array ..say array one , array two , array three and array four .
Now I want when I search on pressing scope bar one only array one values should search ..
on pressing scope bar two only array twovalues should search and so on ..
Is there any method for scope bar button available to search ?
like If( scope_bar==1){...}else
like If i search for scope barone then it will display only array one. is there any method available ..I searched on the apple documentation but could not get
You should read some tutorials about NSDictionary . i have implemented this search on book search app where titles and authors were searched both at same time.
// for each book
NSDictionary * book = NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
title, #"TITLE", author, #"AUTHOR", nil];
[dataSource addObject:book];
after that in search method you can make changes according to your own ease
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[tableData removeAllObjects];
if(searchText != nil && ![searchText isEqualToString:#""]){
for(NSDictionary * book in dataSource){
NSString * title = [book objectForKey:#"TITLE"];
NSString * author = [book objectForKey:#"AUTHOR"];
NSRange titleRange = [[title lowercaseString] rangeOfString:[searchText lowercaseString]];
NSRange authorRange = [[author lowercaseString] rangeOfString:[searchText lowercaseString]];
if(titleRange.location != NSNotFound || authorRange.location != NSNotFound)
[tableData addObject:book];
}
}
[tableView reloadData];
}

sqlite search in multiple column

I have a simple database in iPad Application having couple of tables.
The UI displays the table data properly in a master-detail view controller. I want to add a search feature which will search for the given text in all the field/columns of all the tables and give the result.
One crude way is to write a select query using where clause for each columns. But I believe there will be some proper way for that.
Or is it possible to search the UITableView itself and refresh the data ?
Regards,
nirav
Code for searching in Table
- (void) searchTableView {
NSString *searchText = searchBar.text;
if([searchText length] == 0)
{
[searchArr addObjectsFromArray:userArr];
}
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (int i=0; i<[userArr count]; i++) {
NSString *sTemp = [[userArr objectAtIndex:i] objectForKey:#"name"];
NSRange titleResultsRange = [[sTemp lowercaseString] rangeOfString:[searchText lowercaseString]];
if(titleResultsRange.location != NSNotFound && titleResultsRange.location == 0)
{
[searchArr addObject:[userArr objectAtIndex:i]];
}
}
searchArray = nil;
}

Suggest # tags while typing (like Twitter) for iPhone UITextView

I'd building an app that uses hashtags, like Twitter or Tweetbot. When you're typing a message, if you type the hashtag symbol, I'd like to suggest tags that match the current one you're typing.
I've already figured out how to get the UITableView to appear and show a list of hashtags, but what I can't figure out is how to do the following:
Get the NSRange of the current word being typed,
See if that range is formatted like a hashtag (NSRegularExpression #"#\\w\\w*")
(From here on out, I've got the code figured out to search for matching hashtags and show them in the UITableView)
Can anyone help me with steps 1 and 2? I've been thinking about using textViewDidChange:, but I'm concerned that the app's performance might suffer if I'm constantly running methods every time the characters change.
Thanks!
I figured it out! I wound up using the textViewDidChange: and textViewDidChangeSelection: methods.
To get the NSRange of the current hashtag being typed, I ran a for loop over the NSRegularExpression matches in the text string. From there, I used NSLocationInRange to find out if the current cursor position intersected any of the hashtags.
Here's the code:
//Get the ranges of current hashtags
NSArray *hashtagRanges = [StringChecker rangesOfHashtagsInString:textView.text];
NSTextCheckingResult *currentHashtag;
if ([hashtagRanges count] >0)
{
//List the ranges of all the hashtags
for (int i = 0; i<[hashtagRanges count]; i++)
{
NSTextCheckingResult *hashtag = [hashtagRanges objectAtIndex:i];
//Check if the currentRange intersects the hashtag
//Have to add an extra space to the range for if you're at the end of a hashtag. (since NSLocationInRange uses a < instead of <=)
NSRange currentlyTypingHashtagRange = NSMakeRange(hashtag.range.location, hashtag.range.length + 1);
if (NSLocationInRange(currentRange.location, currentlyTypingHashtagRange))
{
//If the cursor is over the hashtag, then snag that hashtag for matching purposes.
currentHashtag = hashtag;
}
}
if (currentHashtag){
//If we found one hashtag that we're currently editing
//Display the hashtag suggester, feed it the current hashtag for matching.
[self showTagTable];
//Get the current list of hashtags into an array
NSFetchRequest *hashtagRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *tagEntityDescription = [NSEntityDescription entityForName:#"Tags"
inManagedObjectContext:self.note.managedObjectContext];
[hashtagRequest setEntity:tagEntityDescription];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"dateLastUsed"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[hashtagRequest setSortDescriptors:sortDescriptors];
NSPredicate *tagPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", [noteTextView.text substringWithRange:currentHashtag.range]];
[hashtagRequest setPredicate:tagPredicate];
tagsToDisplay = (NSMutableArray *)[self.note.managedObjectContext executeFetchRequest:hashtagRequest error:nil];
[tagListTable reloadData];
//If there are no matching hashtags, then let's hide the tag table.
if ([tagsToDisplay count] == 0)
{
[self hideTagTable];
return;
}
}
The StringChecker class is a custom one that I wrote, it just has class methods that parse the strings. I made StringChecker a class because the methods are used in several places in the app. Here's the method:
#pragma mark - Hashtag Methods
+(NSArray *)rangesOfHashtagsInString:(NSString *)string {
NSRegularExpression *hashtagDetector = [[NSRegularExpression alloc] initWithPattern:#"#\\w\\w*"
options:NSRegularExpressionCaseInsensitive
error:nil];
NSArray *hashtagRanges = [hashtagDetector matchesInString:string
options:NSMatchingWithoutAnchoringBounds
range:NSMakeRange(0, string.length)];
return hashtagRanges;
}
+(NSUInteger)numberOfHashtagsInString:(NSString *)string {
NSRegularExpression *hashtagDetector = [[NSRegularExpression alloc] initWithPattern:#"#\\w\\w*"
options:NSRegularExpressionCaseInsensitive
error:nil];
NSUInteger numberOfHashtags = [hashtagDetector numberOfMatchesInString:string
options:NSRegularExpressionCaseInsensitive
range:NSMakeRange(0, string.length)];
return numberOfHashtags;
}
Another way I figured out to do this is as follows.
In the - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text function I put a listener for a # being typed which begins recording the characters following the hash until the user types a space at which time it resets.
if ([text isEqualToString:#"#"]) {
recordingHashTag = YES;
startParse = range.location;
}else if ([text isEqualToString:#" "]) {
currentHashTag = nil;
recordingHashTag = NO;
theTable.hidden = YES;
}
if (recordingHashTag == YES) {
NSString *value;
if (startParse > [textView.text length] - startParse) {
value = [textView.text substringWithRange:NSMakeRange(startParse, [textView.text length] - startParse)];
[self filterHashTagTableWithHash:value];
}
}
If the BOOL recordingHashTag is set to YES I pass the substring containing the hashtag text to a function which searches a pre populated array of hashtags. If there is a match it adds that entry to a filtered array of hashtags which it uses to populate the tableview on the fly.
-(void)filterHashTagTableWithHash:(NSString *)hash{
[self.filterHashTagArray removeAllObjects];
for (NSString *hashTag in self.hashTagArray ){
NSRange result = [hashTag rangeOfString:hash options:NSCaseInsensitiveSearch];
if (result.location != NSNotFound) {
[filterHashTagArray addObject:hashTag];
}
}
if (filterHashTagArray.count) {
theTable.hidden = NO;
}else{
theTable.hidden = YES;
}
[self.theTable reloadData];
}
The final step is to insert the hash tag when the user clicks on the entry in the table.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = (UITableViewCell*)[self tableView:theTable cellForRowAtIndexPath:indexPath];
NSString *newString = [textViewComment.text stringByReplacingCharactersInRange:NSMakeRange(startParse, [textViewComment.text length] - startParse) withString:cell.textLabel.text];
textViewComment.text = newString;
}
Just don't forget to clear out your variables when a user backspaces mid hash tag.

How to implement UITableView search functionality

My iPhone application has a UITable View implemented with search functionality in it. The values in the table are grouped into sections from A-Z. Whenever a user tap on particular cell in the table it loads a detail view controller which gives all the values of that particular user. Now my problem is whenever I search some contact and tap on a particular user to check his detail view it always returns a contact starting with letter A. So, my doubt is how to implement this search functionality. Is there a way to get the name of the contact I tapped..Please check this screenshot.. For example if I search some contact starting with letter 'B' and tap on that contact it loads the detail view of a contact starting with letter 'A'. I get all the values from the database. Can you please help me out...
This is the code:
The code I wrote here is in a method:
I am getting all the contacts from database and assigning to an array contacts. Then I am grouping all the contacts according to the alphabets and grouping everything into a dictionary with keys as A-Z and values as name of contacts starting with these letters. Now when I search for a particular contact his name may start with either A ,B or Z..so in the search bar when I search for a particular contact for example a contact starting with letter Z, in this case it gives the details of a person with A. I want this to change so that whenever I tap on a particular contact it should load its details. I am unable to figure out how to do it..
contacts = [[db getContacts:#"Contacts"] componentsSeparatedByString:#","];
[db cleanup];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
NSString *charString;
for (int i=65; i<91; i++) {
charString = [NSString stringWithFormat:#"%c",(char *)i];
[tempArray addObject:charString];
}
[charString release];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for (int i=0; i<[tempArray count]; i++) {
NSMutableArray *contactsByIndex = [[[NSMutableArray alloc] init]autorelease];
NSString *tempChar = [tempArray objectAtIndex:i];
for (int j=0; j<[contacts count]-1; j++)
{
NSString *test = [contacts objectAtIndex:j];
NSString *tempString = [test substringToIndex:1];
if ([tempString isEqualToString:tempChar]) {
[contactsByIndex addObject:[contacts objectAtIndex:j]];
}
}
[dict setObject:contactsByIndex forKey:[tempArray objectAtIndex:i]];
}
self.contactNames = dict;
NSArray *array = [[contactNames allKeys] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
self.contactKeys = array;
[dict release];
[tempArray release];
//---display the searchbar---
self.tableView.tableHeaderView = searchBar;
searchBar.autocorrectionType = UITextAutocorrectionTypeYes;
listOfContacts = [[NSMutableArray alloc] init];
for (NSString *key in array)
{
NSArray *contactsArray = [contactNames objectForKey:key];
for (NSString *name in contactsArray) {
[listOfContacts addObject:name];
}
}
- (void) searchContactsTableView {
//---clears the search result---
[searchResult removeAllObjects];
for (NSString *str in listOfContacts) {
NSRange titleResultsRange = [str rangeOfString:searchBar.text options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[searchResult addObject:str];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
NSString *selectedRow=nil;
if (isSearchOn) {
selectedRow=[searchResult objectAtIndex:indexPath.row];
}
DetailViewController *detailViewController;
int section_index=[indexPath indexAtPosition:[indexPath length]-2];
int sugarid_Index = [indexPath indexAtPosition: [indexPath length]-1];
NSString* sectionName=[contactKeys objectAtIndex:section_index];
NSLog(#"%#",sectionName);
//This is a method which gets the details of a particular contact based on the section and the row selected..Contacts is the table name
NSString *getContact=[db getId:#"Contacts" bySection:sectionName andIndex:sugarid_Index];
id=[db getContact:#"Contacts" id:getContact];
// Pass the selected object to the new view controller.
detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
detailViewController.eachContact=contactForSugarId;
[self.navigationController pushViewController:detailViewController animated:YES];
}
When I search for a contact it should search for the name in database and should return its details. Is there a way to do it..please let me know or is there a way to get the name of the cell i.e. the contact name so that I can use that in one of my database methods to retrieve the details of the contact I selected.
Off hand it sounds like you're looking in the wrong array of contacts after the search. You need to have two arrays. One with all the contacts, and one with the filtered contacts. When you search, put all the results in order in the filtered list, and pull the details from that one.
Does this make sense?
If not, try posting a bit of code, and explaining your structure.

markup text parser like stackoverflow's formatter in Objective-C

I'm in the process of creating a markup editor in Objective C. I require the following functionality:
Recognise the demarcation of a block eg **block**
Delete the start and end "tags" eg "The next text is **bold**" becomes "The next text is bold"
Determine the start and end positions of the marked-up text in the new context: "The next text is bold"
Edit:
As I may expand the syntax in the future (it will be very limited at the moment), it is important that parsing be top-down such that the start and end positions of the text always correspond with the resulting text. For this reason regex may not be the best solution.
What is the best way to do this?
In the end went for regex approach using RegexKitLite
The code below is not fully tested but does work with the case St3fan pointed out.
- (NSArray *) scanContent:(NSMutableString **)content {
NSMutableArray *tokens = [[NSMutableArray alloc] init];
NSArray *captureRegex = [[NSArray alloc] initWithObjects:
#"\\[\\[(.*?)\\]\\]",#"\\*\\*(.*?)\\*\\*", nil];
NSArray *tokenID = [[NSArray alloc] initWithObjects:
#"Italic",#"Bold", nil];
int index = 0;
for (NSString*capture in captureRegex) {
NSRange captureRange;
NSRange stringRange;
stringRange.location = 0;
stringRange.length = [*content length];
do {
captureRange = [*content rangeOfRegex:capture inRange:stringRange];
if ( captureRange.location != NSNotFound ) {
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:[tokenID objectAtIndex:index] forKey:#"Token"];
[dictionary setObject:[NSNumber numberWithInt:captureRange.location]
forKey:#"Start"];
[dictionary setObject:[NSNumber numberWithInt:captureRange.length]
forKey:#"Length"];
[tokens addObject:dictionary];
for (NSMutableDictionary *dict in tokens) {
NSNumber *nRange = [dict objectForKey:#"Start"];
int start = [nRange intValue];
if (start > captureRange.location) {
nRange = [NSNumber numberWithInt:start - 4]; // Removing 4 characters
[dict setObject:nRange forKey:#"Start"];
}
if (start == captureRange.location) {
NSString *data = [*content stringByMatching:capture options:RKLMultiline inRange:captureRange capture:1 error:NULL];
NSLog(#"data: %#",data);
[*content replaceOccurrencesOfRegex:capture withString:data range:captureRange];
NSLog(#"Replaced Content: %#",*content);
}
}
stringRange.location = captureRange.location + captureRange.length -4;
stringRange.length = [*content length] - stringRange.location;
}
}
while ( captureRange.location != NSNotFound );
index++;
}
return tokens;
}
MarkDown Sharp, the markdown processor used on the StackExchange websites, is open source. Take a look at the file, perhaps you can see how they do it or port it to objective-c.
Perhaps better yet, take a look at this question: "What is the simplest implementation of Markdown for a Cocoa application?"
It links to an open source application called MarkdownLive which uses a C implementation of Markdown called discount, and also provides an objective-c wrapper for it.