1

我有一个使用 @ 符号的类似于 twitters 的用户名系统。

我通过输入@username 将其设置为向用户发送消息。这与 Twitter 中的提及基本相同。

到目前为止,我已经能够检测到 @ 符号后面的文本,并在它碰到空白时停止检测。这已经用 NSScanner 完美地完成了。

我的问题是如果我想给多个@usernames 发送消息,NSScanner 只会检测到第一次出现。我需要它来检测最新的事件。我发现这是一个有用的工具:

NSRange lastSymbol = [text rangeOfString:@"@" options:NSBackwardsSearch];

我似乎无法弄清楚如何与 NSScanner 一起正确使用它。这是我的代码尝试的 2 个示例。

示例 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);

    }

}

如您所见,我只是不太确定如何使这些协同工作以产生我正在寻找的结果。有任何想法吗?谢谢!

**************************更新*********************** *****

更具体地说,当用户输入 @ 符号并开始输入用户名时,我想根据他们输入的内容显示他们的朋友列表。所以很自然地,我想拉出@符号后面的字符串,并且随着用户不断输入,不断更新他们的朋友列表。一旦用户输入了一个空格,我们假设他们已经输入了用户名(用户名不能包含空格),所以我停止显示表格视图。

到目前为止,上面的代码只是检测并拉取@符号后面的字符串。这是现在的输出:

文本字段文本:你好@username

在此处输入图像描述

这非常有效,正如您所看到的,我可以继续对照一系列朋友检查此文本。

假设用户想用相同的文本向另一个用户发送消息,如下所示:

你好@username,这是我的朋友@goodfriend

这次它仍然显示第一个@username,但忽略第二个@goodfriend。

我认为最好的方法是告诉 NSScanner 引用最后一次出现的 @ 符号,因为我现在只引用第一个 @ 符号。

这也可能与我检测空白以知道用户已完成输入用户名的方式有关,并且不需要更多建议。

希望这会有所帮助,谢谢!

4

2 回答 2

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];
    ...
于 2013-09-07T22:37:48.127 回答
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。

其余的按预期工作。希望这对其他人有帮助!

于 2013-09-07T23:23:28.540 回答