我有一个类似于使用@符号的twitters的用户名系统。
我已将其设置为通过键入@username来向用户发送消息。这与推特中的提及基本相同。
到目前为止,我已经能够检测@符号后面的文本并停止检测它何时到达空白区域。这与NSScanner完美结合。
我的问题是如果我想要发送多个@usernames,NSScanner将只检测第一次出现。我需要它来检测最新的事件。我发现这是一个有用的工具:
NSRange lastSymbol = [text rangeOfString:@"@" options:NSBackwardsSearch];
我似乎无法弄清楚如何与NSScanner一起正确使用它。以下是我的代码尝试的两个示例。
示例1:
NSString *user = nil;
NSString *text = textView.text;
NSRange lastSymbol = [text rangeOfString:@"@" options:NSBackwardsSearch];
if (lastSymbol.location != NSNotFound) {
NSScanner *userScanner = [NSScanner scannerWithString:text];
[userScanner scanUpToString:@"@" intoString:nil];
NSCharacterSet *charset = [NSCharacterSet characterSetWithCharactersInString:@"@"];
if (![userScanner isAtEnd]) {
[userScanner scanUpToCharactersFromSet:charset intoString:nil];
[userScanner scanCharactersFromSet:charset intoString:nil]
[userScanner scanUpToCharactersFromSet:charset intoString:&user];
}
}
if (user.length > 0) {
NSRange whiteSpaceRange = [user rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]];
if (whiteSpaceRange.location != NSNotFound) {
// White space, username has ended
} else {
// Still getting username
NSLog(@"%@", user);
}
}
正如您所看到的,我不太确定如何将这些工作结合起来以产生我正在寻找的结果。有任何想法吗?谢谢!
************************** UPDATE ******************** ********
更具体地说,当用户键入@符号并开始输入用户名时,我想根据他们键入的内容显示他们的朋友列表。很自然地,我想在@符号后面拉出字符串,并且当用户继续输入时,不断更新他们的朋友列表。一旦用户键入一个空格,我们就会假设他们输入了用户名(用户名不能包含空格),所以我就停止显示表视图。
到目前为止,上面的代码只是检测并拉出@符号后面的字符串。这是现在的输出:
文本字段文本:Hello @username
这非常有效,因为你可以看到我可以继续对一群朋友检查这个文本。
假设用户希望在同一文本中向其他用户发送消息,如下所示:
Hello @username,这是我的朋友@goodfriend
这次它仍会显示第一个@username,但忽略第二个@goodfriend。
我认为最好的方法是以某种方式告诉NSScanner引用@符号的最后一次出现,因为我现在所拥有的只是引用第一个@符号。
这可能还与我检测空白区域的方式有关,以便知道用户输入了用户名,并且不再需要任何建议。
希望这有帮助,谢谢!
答案 0 :(得分:2)
对于使用这样的实时输入,我建议使用完全不同的方法。不要寻找最后一个“@”,而是查看最后一个单词,看看它是否以“@”开头。
NSString *user = nil;
NSString *text = textView.text;
// Find the last whitespace character
NSCharacterSet *whitespace = [NSCharacterSet whitespaceCharacterSet];
NSRange lastWordRange = [text rangeOfCharacterFromSet:whitespace options:NSBackwardsSearch];
// If found, get the index after it. Otherwise, the entire string is one word.
if(lastWordRange.location != NSNotFound)
lastWordRange.location += lastWordRange.length;
else lastWordRange.location = 0;
// If the index is not at the end, look for a '@' right after it
if(lastWordRange.location < [text length] &&
[text characterAtIndex:lastWordRange.location] == '@') {
// Found a '@', use the rest of the string as the username
user = [text substringFromIndex:lastWordRange.location+1];
}
if(user) NSLog(@"%@", user); // The user is still typing a name
如果您真的想使用扫描仪,可以使用相同的substringFromIndex:
方法来获取要扫描的子字符串。
NSRange lastSymbol = [text rangeOfString:@"@" options:NSBackwardsSearch];
if (lastSymbol.location != NSNotFound) {
NSString *substring = [text substringFromIndex:lastSymbol.location];
NSScanner *userScanner = [NSScanner scannerWithString:substring];
...
答案 1 :(得分:0)
所以这是我提出的解决方案。 @ugjoavgfhw有一个方法也适用于我所做的有限测试。
这是我的解决方案:
NSString *user = nil;
NSString *text = textView.text;
NSRange lastSymbol = [text rangeOfString:@"@" options:NSBackwardsSearch];
NSScanner *userScanner = [NSScanner scannerWithString:text];
if (lastSymbol.location < 140) {
[userScanner setScanLocation:lastSymbol.location];
}
[userScanner scanUpToString:@"@" intoString:nil];
NSCharacterSet *charset = [NSCharacterSet characterSetWithCharactersInString:@"@"];
if (![userScanner isAtEnd]) {
if (lastSymbol.location != NSNotFound) {
[userScanner scanUpToCharactersFromSet:charset intoString:nil];
[userScanner scanCharactersFromSet:charset intoString:nil];
[userScanner scanUpToCharactersFromSet:charset intoString:&user];
}
}
if (user.length > 0) {
NSRange whiteSpaceRange = [user rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]];
if (whiteSpaceRange.location != NSNotFound) {
// White space, username has ended
} else {
// Still getting username
NSLog(@"%@", user);
}
}
为了清楚起见,这个代码在委托方法中调用:
- (void)textViewDidChange:(UITextView *)textView
每次文本更新时,我们都会执行向后搜索以查找@符号。这被分配给NSRange。
然后创建NSScanner。之后我们检查lastSymbol.location以确保它低于140个字符(格式与具有有限字符的twitter相同)。
如果是,则我们将扫描位置分配给NSScanner。
其余的按预期工作。希望这有助于其他人!