[解決済み】Swift RangeからNSRange?
質問
問題あり。 NSAttributedStringはNSRangeを取るが、Rangeを使うSwift Stringを使用している
let text = "Long paragraph saying something goes here!"
let textRange = text.startIndex..<text.endIndex
let attributedString = NSMutableAttributedString(string: text)
text.enumerateSubstringsInRange(textRange, options: NSStringEnumerationOptions.ByWords, { (substring, substringRange, enclosingRange, stop) -> () in
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: substringRange)
}
})
以下のエラーを発生させます。
error: 'Range' is not convertible to 'NSRange' attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: substringRange) です。
どのように解決するのですか?
スウィフト
String
の範囲と
NSString
の範囲は互換性がありません。
たとえば、?のような絵文字は1つのSwift文字としてカウントされますが、2つの
NSString
文字(いわゆるUTF-16サロゲートペア)です。
したがって、あなたが提案した解決策は、文字列がある場合、予期しない結果を生成します。 が含まれています。例
let text = "????????????Long paragraph saying!"
let textRange = text.startIndex..<text.endIndex
let attributedString = NSMutableAttributedString(string: text)
text.enumerateSubstringsInRange(textRange, options: NSStringEnumerationOptions.ByWords, { (substring, substringRange, enclosingRange, stop) -> () in
let start = distance(text.startIndex, substringRange.startIndex)
let length = distance(substringRange.startIndex, substringRange.endIndex)
let range = NSMakeRange(start, length)
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: range)
}
})
println(attributedString)
出力します。
?長いパラグラ{? }ph say{ NSColor = "NSCalibratedRGBColorSpace 1 0 0 1"。 }ing! }
ご覧の通り、"ph say"に属性が付与され、"saying"には付与されていない。
以来
NS(Mutable)AttributedString
最終的には
NSString
と
NSRange
というのは、実は
に変換したほうがよいでしょう。
NSString
を最初に指定します。それから
substringRange
は
NSRange
で、もうレンジを変換する必要はありません。
let text = "????????????Long paragraph saying!"
let nsText = text as NSString
let textRange = NSMakeRange(0, nsText.length)
let attributedString = NSMutableAttributedString(string: nsText)
nsText.enumerateSubstringsInRange(textRange, options: NSStringEnumerationOptions.ByWords, { (substring, substringRange, enclosingRange, stop) -> () in
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: substringRange)
}
})
println(attributedString)
出力します。
?長い段落{? と言っている。 NSColor = "NSCalibratedRGBColorSpace 1 0 0 1"。 }!{ }
Swift 2に対応したアップデートを行いました。
let text = "????????????Long paragraph saying!"
let nsText = text as NSString
let textRange = NSMakeRange(0, nsText.length)
let attributedString = NSMutableAttributedString(string: text)
nsText.enumerateSubstringsInRange(textRange, options: .ByWords, usingBlock: {
(substring, substringRange, _, _) in
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: substringRange)
}
})
print(attributedString)
Swift 3に対応したアップデートを行いました。
let text = "????????????Long paragraph saying!"
let nsText = text as NSString
let textRange = NSMakeRange(0, nsText.length)
let attributedString = NSMutableAttributedString(string: text)
nsText.enumerateSubstrings(in: textRange, options: .byWords, using: {
(substring, substringRange, _, _) in
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.red, range: substringRange)
}
})
print(attributedString)
Swift 4に対応したアップデートを行いました。
Swift 4 (Xcode 9) の時点で、Swift 標準ライブラリ
の間で変換するメソッドを提供します。
Range<String.Index>
と
NSRange
.
に変換する。
NSString
が不要になりました。
let text = "????????????Long paragraph saying!"
let attributedString = NSMutableAttributedString(string: text)
text.enumerateSubstrings(in: text.startIndex..<text.endIndex, options: .byWords) {
(substring, substringRange, _, _) in
if substring == "saying" {
attributedString.addAttribute(.foregroundColor, value: NSColor.red,
range: NSRange(substringRange, in: text))
}
}
print(attributedString)
こちら
substringRange
は
Range<String.Index>
に変換され、それが
たいこう
NSRange
をもって
NSRange(substringRange, in: text)
関連
-
[解決済み】Git リポジトリから .DS_Store ファイルを削除するには?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] Swiftベースのアプリケーションは、OS X 10.9/iOS 7以下でも動作しますか?
-
[解決済み] Unwind segueは何に使うのか、どう使うのか?
-
[解決済み] UITextFieldのテキストインセット?
-
[解決済み] ぼかしの入ったオーバーレイビューの作成
-
[解決済み】NSRangeからRange<String.Index>へ。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[iOS]コンパイルエラー:ld: アーキテクチャ x86_64 のシンボルが見つかりません。
-
[解決済み] iOS 8 UITableViewのセパレータインセット0が機能しない件
-
[解決済み] Unwind segueは何に使うのか、どう使うのか?
-
[解決済み] UITableViewCell、スワイプ時に削除ボタンを表示させる
-
[解決済み] UITextViewのマージン/パディングをなくす方法
-
[解決済み] セキュリティで保護されたWebサービスにもアクセスするiOSアプリで、Facebook認証を行うためのデザイン
-
[解決済み] iPhoneでナビゲーションバーを1ページ目だけ非表示にする
-
[解決済み】NSAttributedStringはどのように使うのですか?
-
[解決済み】NSRangeからRange<String.Index>へ。
-
[解決済み】Swiftで正規表現にマッチしたものを取り出す