選択範囲の文字に装飾したい
2018-04-16
まずは、出来上がりのフォームはこちら
TextViewで編集することを想定しているので、NSTextViewを使ったやり方になります。
文字の装飾といっても、文字の色を変更するとか、そういうのではないのですが、選択した文字の前後にHTMLのタグを入れたいというのが、今回の目的となります。
ボタンをクリックしたらそうなる。
なので、今回のコードはそのボタンの関数の中身だけをやってみます。
ということで、早速コードです。
// 選択開始 let location = tv.selectedRange().location if location == -1 { // 選択開始位置が−1なら何もしないで終了 return } // 選択範囲 let length = tv.selectedRange().length if length == 0 { // 選択範囲が0なら何もしないで終了 return } let length2 = location + (length - 1) let selectedString = (tv.textStorage as! NSTextStorage).string // 選択されている部分を取り出す let text = selectedString.substring(location...length2) // 選択範囲より前の部分を取り出す let before = selectedString.substring(0...(location - 1)) // 選択範囲より後ろを取り出す let after = selectedString.substring((length2 + 1)...) // 前に付けるタグ let beforeTag = "<strong>" // 後ろに付けるタグ let afterTag = "</strong>" // 文章を作成する let answer = before + beforeTag + text + afterTag + after tv.textStorage?.setAttributedString(NSAttributedString(string: String(answer)))
まず、選択されている文字列の位置関係を明確にしないといけません。
「tv」という変数は「NSTextView」の変数としています。
ということで、「tv.selectedRange().location」で選択開始位置を取得しています。
その次の行で、開始位置が-1なら何もしないで終了させるようにしています。
次に選択範囲として何文字選択されているのか、「tv.selectedRange().length」で取得します。
これは選択開始位置から何文字なのか?というものなので、最初から数えてどこまでなのかというわけではありません。
その次の行ではその範囲の文字数が0なら何もせずに終了としています。
それ以降は文字を取り出す処理をしています。
最初から選択範囲が始まる位置まで、選択範囲が始まる位置から終わる位置まで、選択範囲が終わった位置から後ろまでと、細かく分割しています。
ちなみに、「substring」という関数は拡張しています。
extension String { func substring(_ r: CountableRange<Int>) -> String { let length = self.count let fromIndex = (r.startIndex > 0) ? self.index(self.startIndex, offsetBy: r.startIndex) : self.startIndex let toIndex = (length > r.endIndex) ? self.index(self.startIndex, offsetBy: r.endIndex) : self.endIndex if fromIndex >= self.startIndex && toIndex <= self.endIndex { return String(self[fromIndex..<toIndex]) } return String(self) } func substring(_ r: CountableClosedRange<Int>) -> String { let from = r.lowerBound let to = r.upperBound return self.substring(from..<(to+1)) } func substring(_ r: CountablePartialRangeFrom<Int>) -> String { let from = r.lowerBound let to = self.count return self.substring(from..<to) } func substring(_ r: PartialRangeThrough<Int>) -> String { let from = 0 let to = r.upperBound return self.substring(from..<to) } }
これは拾いものです。
ちょうどいいプログラムがあったので、拝借しました。
使わせて頂きます。
実際に実行してみます。
で、とりあえず、文字を適当に入力します。
文字を選択して、ボタンをクリックします。すると、その選択範囲の前後にタグがついたことを確認できます。
コメントを残す