2017-02-01 4 views
0

私はUITextViewを持っており、それをタップしてテキストの単語を選択することができます。タップされている場合は、NSForegroundColor属性を変更することにより、単語が色で強調表示されます。 再度タップすると、色をテキストカラーに戻して選択を解除します。属性付き文字列の色が変更された単語を取得する

今、私はUITextViewのすべての選択された単語を知る必要があります。

最初のアイデアは、特殊文字であるすべてを削除し、スペースでテキストを分割することでした。次に、色属性が選択された/強調表示された各別の単語の色と等しいかどうかを確認します。 しかし、属性付き文字列は、文字の分割やコンポーネントの削除を許可していません。どちらもNSAttributedStringです。

2番目のアイデアは、強調表示された部分の範囲を配列に保存し、強調表示された部分を取得するために反復処理することでした。しかし、これは私にとってはやや複雑すぎるようです。特に、配列で保証されていない単語の正しい順序が必要なので、各タップで追加/削除してください(例:テキストは次のようになります。テスト」

Tap this -> index 0 
Tap test -> index 1 
Tap this -> test becomes index 0 
Tap this -> this becomes index 1 

その後、順番はもう良いではありません。

私はすでに起因する文字列の色を取得する方法を考え出した。それは問題ではない。

どのように反復処理することができます原因となった文字列を分析し、色が変わった単語や、この問題を解決する最善の方法を見つけ出しますか?

ありがとうございました!

挨拶

答えて

2

あなたは色の属性を探して属性付き文字列を反復処理することができます。このコードは、属性付きの文字列を処理

This{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} is { 
}a{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} test { 
}of{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} the following code{ 
} 

// This generates a test attributed string. 
// You actually want the attributedText property of your text view 
let str = NSMutableAttributedString(string: "This is a test of the following code") 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(0, 4)) 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(8, 1)) 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(15, 2)) 
print(str) 

上記プリント:

次のコードは、方法を示しています。フォアグラウンドカラーでフォーマットされたテキストの範囲は、単語配列に入れられます。

var words = [String]() 
str.enumerateAttribute(NSForegroundColorAttributeName, in: NSMakeRange(0, str.length), options: []) { (value, range, stop) in 
    if value != nil { 
     let word = str.attributedSubstring(from: range).string 
     words.append(word) 
    } 
} 
print(words) 

この版画:

[ "この"、 "A"、 "の"]提案のため

+0

ありがとう、魅力のように動作します! –

0

私がこの範囲に基づいて、あなたはこの言葉の外観ではなく、他の方法をカスタマイズすることができ、その後、選択した範囲のためのストレージのいくつかの種類を作成することを提案することができます。これは、テキスト全体の属性をチェックすることなく、毎回選択された単語にアクセスすることを可能にします。

+0

感謝。 なぜ私はあなたがそれを提案するのか理解しているので、私のプロジェクトが文字列全体を一度反復することは重要ではないので、私は他のアプローチに固執します。 –

0

私は、あなたの質問に答えるために、Rangesを格納する必要がありPiotrに同意しながら:

attributedString.enumerateAttributes(in: NSMakeRange(0, attributedString.length), options: []) { attributes, range, _ in 
    if let color = attributes[NSForegroundColorAttributeName] as? UIColor, 
     color == YOUR_HIGHLIGHT_COLOR { 
     let nString = attributedString.string as NSString 
     let word = nString.substring(with: range) 
     // Do what you want with the word 
    } 
} 
関連する問題