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!
iphone ios regex uitextview nsregularexpression
add a comment |
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!
iphone ios regex uitextview nsregularexpression
add a comment |
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!
iphone ios regex uitextview nsregularexpression
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!
iphone ios regex uitextview nsregularexpression
iphone ios regex uitextview nsregularexpression
edited Jun 29 '13 at 16:51
Alan Moore
60.8k979132
60.8k979132
asked Nov 26 '11 at 19:46
bryanjclarkbryanjclark
4,01512558
4,01512558
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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;
}
This works great! Awesome code!!
– Kevin van Mierlo
Jan 6 '14 at 16:20
Thanks very much! :)
– bryanjclark
Jan 6 '14 at 19:18
I tried, but some of the error occured, Can you send this sample
– SBM
Sep 16 '15 at 11:13
add a comment |
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.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f8281098%2fsuggest-tags-while-typing-like-twitter-for-iphone-uitextview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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;
}
This works great! Awesome code!!
– Kevin van Mierlo
Jan 6 '14 at 16:20
Thanks very much! :)
– bryanjclark
Jan 6 '14 at 19:18
I tried, but some of the error occured, Can you send this sample
– SBM
Sep 16 '15 at 11:13
add a comment |
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;
}
This works great! Awesome code!!
– Kevin van Mierlo
Jan 6 '14 at 16:20
Thanks very much! :)
– bryanjclark
Jan 6 '14 at 19:18
I tried, but some of the error occured, Can you send this sample
– SBM
Sep 16 '15 at 11:13
add a comment |
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;
}
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;
}
edited Dec 15 '14 at 15:01
rihe
1,18832047
1,18832047
answered Dec 3 '11 at 21:51
bryanjclarkbryanjclark
4,01512558
4,01512558
This works great! Awesome code!!
– Kevin van Mierlo
Jan 6 '14 at 16:20
Thanks very much! :)
– bryanjclark
Jan 6 '14 at 19:18
I tried, but some of the error occured, Can you send this sample
– SBM
Sep 16 '15 at 11:13
add a comment |
This works great! Awesome code!!
– Kevin van Mierlo
Jan 6 '14 at 16:20
Thanks very much! :)
– bryanjclark
Jan 6 '14 at 19:18
I tried, but some of the error occured, Can you send this sample
– SBM
Sep 16 '15 at 11:13
This works great! Awesome code!!
– Kevin van Mierlo
Jan 6 '14 at 16:20
This works great! Awesome code!!
– Kevin van Mierlo
Jan 6 '14 at 16:20
Thanks very much! :)
– bryanjclark
Jan 6 '14 at 19:18
Thanks very much! :)
– bryanjclark
Jan 6 '14 at 19:18
I tried, but some of the error occured, Can you send this sample
– SBM
Sep 16 '15 at 11:13
I tried, but some of the error occured, Can you send this sample
– SBM
Sep 16 '15 at 11:13
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited Dec 15 '14 at 14:58
rihe
1,18832047
1,18832047
answered Jun 7 '13 at 17:21
BuenoBueno
1,1551111
1,1551111
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f8281098%2fsuggest-tags-while-typing-like-twitter-for-iphone-uitextview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown