私はUITextView
を持っていて、ユーザーがそれにテキストを入力しているときに、その場でテキストをフォーマットしたいと思います。構文の強調表示のようなもの...
そのため、UITextView
...を使用します.
すべてが正常に機能し、1つの問題が予想されます。テキストビューからテキストを取得し、そこからNSAttributedString
を作成します。この属性付き文字列をいくつか編集し、textView.attributedText
。
これは、ユーザーが入力するたびに発生します。したがって、selectedTextRange
を編集する前にattributedText
を覚えておき、後で設定し直して、ユーザーが以前入力していた場所で引き続き入力できるようにする必要があります。唯一の問題は、テキストがスクロールを必要とするのに十分な長さになると、ゆっくり入力するとUITextView
が一番上にスクロールし始めるということです。
ここにいくつかのサンプルコードがあります:
- (void)formatTextInTextView:(UITextView *)textView
{
NSRange selectedRange = textView.selectedRange;
NSString *text = textView.text;
// This will give me an attributedString with the base text-style
NSMutableAttributedString *attributedString = [self attributedStringFromString:text];
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
NSArray *matches = [regex matchesInString:text
options:0
range:NSMakeRange(0, text.length)];
for (NSTextCheckingResult *match in matches)
{
NSRange matchRange = [match rangeAtIndex:0];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:matchRange];
}
textView.attributedText = attributedString;
textView.selectedRange = selectedRange;
}
CoreTextを直接使用せずに解決策はありますか?テキストを選択するUITextView
s機能が好きです...
これが正しい解決策かどうかはわかりませんが、うまくいきます。
テキストをフォーマットする前にスクロールを無効にし、フォーマット後に有効にするだけです
- (void)formatTextInTextView:(UITextView *)textView
{
textView.scrollEnabled = NO;
NSRange selectedRange = textView.selectedRange;
NSString *text = textView.text;
// This will give me an attributedString with the base text-style
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
NSArray *matches = [regex matchesInString:text
options:0
range:NSMakeRange(0, text.length)];
for (NSTextCheckingResult *match in matches)
{
NSRange matchRange = [match rangeAtIndex:0];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:matchRange];
}
textView.attributedText = attributedString;
textView.selectedRange = selectedRange;
textView.scrollEnabled = YES;
}
自分自身でSergeysの回答を使用して、Swift 2:
func formatTextInTextView(textView: UITextView) {
textView.scrollEnabled = false
let selectedRange = textView.selectedRange
let text = textView.text
// This will give me an attributedString with the base text-style
let attributedString = NSMutableAttributedString(string: text)
let regex = try? NSRegularExpression(pattern: "#(\\w+)", options: [])
let matches = regex!.matchesInString(text, options: [], range: NSMakeRange(0, text.characters.count))
for match in matches {
let matchRange = match.rangeAtIndex(0)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: matchRange)
}
textView.attributedText = attributedString
textView.selectedRange = selectedRange
textView.scrollEnabled = true
}
Swift 4:
func createAttributedText() {
let stringText = "Test String"
let stringCount = stringText.count
let string: NSMutableAttributedString = NSMutableAttributedString(string: stringText)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSMakeRange(0, stringCount))
self.textView.attributedText = string
}
Swift 2.0:
let myDisplayTxt:String = "Test String"
let string: NSMutableAttributedString = NSMutableAttributedString(string: self.myDisplayTxt)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSMakeRange(0, 5))
string.addAttribute(String(kCTForegroundColorAttributeName), value: UIColor.redColor().CGColor as AnyObject, range: NSMakeRange(0, 5))
self.sampleTextView.attributedText = string