【问题标题】:How to avoid splitting a word over two UITextViews如何避免在两个 UITextViews 上拆分一个单词
【发布时间】:2011-05-20 08:18:36
【问题描述】:

我想这是一个有点尴尬的问题,所以让我用一个插图重新表述一下:

我有一个 UITextView,它仅限于一定数量的字符。这会定期通过- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)aRange replacementText:(NSString *)aText 进行检查。一旦文本大于阈值保持(在插图中为 8 个字符),应用程序将更改为下一个 textView 并将输入的下一个字符(在本例中为 p)复制到新的 UITextView。然后用户可以输入单词的其余部分(在本例中为 py)。

我不想将单词拆分为两个 UITextView,而是希望在下一个 UITextView 中包含整个单词“happy”。换句话说,我需要将字符串 1 中的 'hap' 复制到字符串 2 的开头,然后从字符串 1 中删除 'hap'。

我想出了这段代码,它检查字符串 1 中的空格并将空格后面的所有内容复制到字符串 2 中。但它不起作用:

NSLog(@"text of current string: %@", aTextView.text);           // e.g. "I am hap"
         NSLog(@"chars in aTextView.text: %i", aTextView.text.length);  // e.g. 8 chars
         NSLog(@"text for next string: %@ ", aText);                    // e.g. "py"

         NSString *aTextModified = aText;

         for (int i = aTextView.text.length; i > 0; i--) {

             NSLog(@"I currently check: '@%'", [aTextView.text characterAtIndex:i]);

             if ([[aTextView.text characterAtIndex:i] isEqualToString:@" "]) {
                 // job done
             } else {
                 NSLog(@"I add %@ infront of %@", [aTextView.text characterAtIndex:i], aText);
                 aTextModified = [NSString stringWithFormat:@"%@%@", [aTextView.text characterAtIndex:i], aText];
                 NSLog(@"I delete %@ as I have put it into the next string...", [aTextView.text characterAtIndex:i]);
                 [aTextView.text characterAtIndex:i] = @"";
             }
         }

XCode 为我的行 if ([[aTextView.text characterAtIndex:i] isEqualToString:@" "]) 提供警告“无效的接收器类型 'unichar'”。我想我没有使用 characterAtIndex 对吗?我是否不允许将其应用于 UITextView 中的文本(应该是 UIString)?

另外,我在最后一行 [aTextView.text characterAtIndex:i] = @""; 收到错误“LValue required as left opperand of assignment”,我想我真的不明白如何访问 UITextView 中的字符并对其进行修改。

如果有任何关于如何正确执行此操作的建议,以及是否有更简单的方法来实现我正在尝试做的事情,我将不胜感激。

【问题讨论】:

  • 如果单词大于阈值会怎样?
  • @Nick Weaver:嗯,它不能大于阈值,因为它会被自动切断。例如。如果您尝试输入“areallylongword”,它将在“areallylo”之后被截断,并且“n”将被放入下一个字符串中。我在输入每个字符后检查字符串。此外,我的字符串 1 和 2 比 8 个字符大得多——我只是将其用于说明目的,以保持简单。实际上,我正在查看整个 UITextView 填充屏幕...问题是检查在此屏幕上输入的最后一个单词以及是否需要将其放在下一个屏幕上。非常感谢您的帮助

标签: iphone objective-c cocoa-touch uitextview


【解决方案1】:

几件事

NSLog(@"I currently check: '@%'", [aTextView.text characterAtIndex:i]);

你在这里得到一个C 字符,所以你应该改用%c

[[aTextView.text characterAtIndex:i] isEqualToString:@" "]

同样,您在这里所做的是向不正确的C 字符发送消息。您可以将其更改为[aTextView.text characterAtIndex:i] == " " 以正确执行此操作。

[aTextView.text characterAtIndex:i] = @"";

text 被定义为不可变字符串。你不能像这样改变它。您必须声明一个可变字符串并将text 的内容复制过来。修改可变字符串后,可以设置为text

这也会给你最后一句话。

NSScanner *wordsScanner = [NSScanner scannerWithString:@"I am happy however I want the last word and it's positions !!!!"];
NSString *theLastWord;
while (![wordsScanner isAtEnd]) {
    [wordsScanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:&theLastWord];
}

// theLastWord has the value.

编辑

NSString *text = aTextView.text;
int index = text.length - 1;
while ([text characterAtIndex:index] != " ") {
    index--;
}

NSString stringToBeMoved = [text substringFromIndex:index];
aTextView.text = [text substringToIndex:(index+1)];

【讨论】:

  • 非常感谢。我会试一试,告诉你进展如何。
  • 实际上,我对声明一个可变字符串然后将文本内容复制过来有点困惑......我将如何做到这一点?简单的Char replacementChar = ""; 然后[aTextView.text characterAtIndex:i] = replacementChar; 不会工作,对吧?
【解决方案2】:

好的,让我们从简单的开始。我创建了以下正则表达式,它将匹配字符串中的最后一个单词以及是否存在空格或标点符号等非单词字符。

我认为使用正则表达式并确定它匹配的位置来操作字符串会更容易。但是我不确定大文本的性能如何,但我认为可以通过使用一些假设来解决,例如:textview one won't skip inside the first 1000 characters so it may be safe to use only the last 50 characters for正则表达式。

NSString *aString = @"I am happy however I want the last word and it's positions !!!!";

NSString * const regularExpression = @"\\b(\\w+)\\b(\\W*)$";

NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regularExpression
                                                                       options:NSRegularExpressionCaseInsensitive | NSRegularExpressionUseUnicodeWordBoundaries
                                                                         error:&error];

NSArray *matches = [regex matchesInString:aString
                                  options:0
                                    range:NSMakeRange(0, [aString length])];

for (NSTextCheckingResult *match in matches) {
    for (int i = 0; i < [match numberOfRanges]; i++) {
        NSLog(@"substring %d: %@", i, [aString substringWithRange:[match rangeAtIndex:i]]);
    }
}

如果匹配,您可以轻松地遍历结果,从而为您提供最后一个单词和一些尾随非单词字符,但最重要的是您可以获得每个匹配项的范围,以便确定是否超过阈值。

【讨论】:

  • 谢谢尼克。但我想问题是我没有得到完整的字符串。我一次只能得到一个角色!请记住,我使用的是- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)aRange replacementText:(NSString *)aText——所以我只得到一个通常只有一个字符的文本。换句话说,应用程序会在您键入每个字符时不断检查。如果您尝试添加另一个字符并越过阈值,我想分隔我尝试输入的最后一个单词的开头(例如,我无法再输入的位置)。我想将“positi”复制到下一个 UITextView。
  • 我会尝试在你的代码中工作,让你知道我卡在哪里了。我想我最大的问题是我没有使用 NSMakeRange...
  • @n.evermind 你可以切换到委托方法textViewDidChange 并且只使用 myTextField.text 作为输入,所以每次用户点击一个键时都会进行检查。
猜你喜欢
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多