在为iPhone UITextViewinput(如Twitter)时build议#标签

我会build立一个使用Twitter或Tweetbot等标签的应用程序。 当你input信息时,如果你input了标签符号,我想build议与你正在input的标签匹配的标签。

我已经想出了如何让UITableView出现,并显示标签列表,但我不明白如何做到以下几点:

  1. 获取正在键入的当前单词的NSRange
  2. 看看这个范围是否被格式化为一个hashtag( NSRegularExpression @"#\\w\\w*"
  3. (从这里开始,我已经find了代码来search匹配的标签并在UITableView中显示它们)

任何人都可以帮我步骤1和2? 我一直在考虑使用textViewDidChange:但是我担心如果每次字符改变时我都会不停地运行方法,那么应用程序的性能可能会受到影响。

谢谢!

我想到了! 我结束了使用textViewDidChange:textViewDidChangeSelection:方法。

为了获得当前hashtag被键入的NSRange ,我对文本string中的NSRegularExpression匹配运行了一个for循环。 从那里,我用NSLocationInRange找出当前光标位置是否与任何一个NSLocationInRange相交。

代码如下:

 //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; } } 

StringChecker类是我写的一个自定义的类,它只是具有parsingstring的类方法。 我做了一个StringChecker类,因为这些方法在应用程序的几个地方使用。 这里的方法是:

  #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; } 

我想通过另一种方式来做到这一点如下。

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text函数我把一个#的侦听器键入,开始logging散列后面的字符,直到用户键入一个空格此时它重置。

 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]; } } 

如果将BOOL recordingHashTag设置为YES则将包含hashtag文本的substring传递给search预先填充的hashtags数组的函数。 如果存在匹配,则将该条目添加到用于填充dynamictableview的经过滤的哈希标签数组中。

 -(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]; } 

最后一步是在用户单击表中的条目时插入散列标签。

  - (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; } 

当用户退出中间哈希标记时,不要忘记清除variables。