2017-08-03 12 views
0

スウィフト(< 4)のRange<String.Index>NSRangeに変換するには、先にStringNSStringに変換しないでください。Range <String.Index>をNSRangeに変換する方法は?

私がこれをしたい理由は、Range<String.Index>の値を使用してUITextViewselectedTextプロパティを設定する必要があるためです。

代替ソリューション:UITextInput.selectedTextRangeRange<String.Index>の値に設定するにはどうすればよいですか?

+1

デュープ? [Swift RangeのNSRange?](https://stackoverflow.com/q/27040924/2415822)。 NSStringに橋渡ししたくない理由は何ですか?また、その質問に対する答えには、NSString以外の解決策がいくつかあります。 – JAL

+0

NSStringへのブリッジは、純粋で直感的で理解でき、自己文書化し、読みやすく、シンプルで、美しく、効率的ではないようです。 emojisを含む文字列の場合、その質問に対する 'NSString'以外の解決策はありません。 – ma11hew28

答えて

6

文字列のUTF16ビューでString.IndexのsamePosition(in :)メソッドを使用します。 NSStringはUTF16を使用するので、UTF16インデックスはNSStringがNSRangeに期待するインデックスと同じでなければなりません。

EDIT:

public extension NSRange { 
    private init(string: String, lowerBound: String.Index, upperBound: String.Index) { 
     let utf16 = string.utf16 

     let lowerBound = lowerBound.samePosition(in: utf16) 
     let location = utf16.distance(from: utf16.startIndex, to: lowerBound) 
     let length = utf16.distance(from: lowerBound, to: upperBound.samePosition(in: utf16)) 

     self.init(location: location, length: length) 
    } 

    public init(range: Range<String.Index>, in string: String) { 
     self.init(string: string, lowerBound: range.lowerBound, upperBound: range.upperBound) 
    } 

    public init(range: ClosedRange<String.Index>, in string: String) { 
     self.init(string: string, lowerBound: range.lowerBound, upperBound: range.upperBound) 
    } 
} 
+0

なぜ複写に回答しますか? – JAL

+1

私は答えを書いていたときに重複としてマークされていませんでした。私はそれを提出する前に右に刻んだ重複マークのように見えます。 –

+0

まあ、私は他の人のあなたの答えを好む。 'NSRange(range、in:string)'のように呼び出すことができるメソッドのコードを提供できますか? – ma11hew28

関連する問題