2017-08-03 2 views
0

Comment puis-je convertir Range<String.Index> en NSRange dans Swift (< 4) sans d'abord convertir le String en NSString?Comment convertir Range <String.Index> en NSRange?

La raison pour laquelle je veux faire cela est que je veux définir une propriété selectedTextUITextView en utilisant une valeur Range<String.Index>. Solution alternative: Comment définir UITextInput.selectedTextRange avec une valeur Range<String.Index>?

+1

Dupe? [NSRange de Swift Range?] (Https://stackoverflow.com/q/27040924/2415822). Une raison pour laquelle vous ne voulez pas passer à NSString? En outre, il existe des solutions non-NSString dans les réponses à cette question. – JAL

+0

La transition vers 'NSString' ne semble pas pure, intuitive, compréhensible, auto-documentée, lisible, simple, belle ou efficace. Aucune des solutions non-'NSString' de cette question ne fonctionne pour les chaînes contenant des emojis. – ma11hew28

Répondre

6

Utilisez la méthode samePosition (in :) de String.Index avec la vue UTF16 de la chaîne. NSString utilise UTF16, donc les index UTF16 doivent être identiques aux index que NSString attend pour 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

Pourquoi répondre à un doublon? – JAL

+1

Il n'était pas marqué comme doublon lorsque j'écrivais la réponse. On dirait que la marque en double a grincé juste avant que je l'ai soumis. –

+0

Eh bien, je préfère votre réponse à l'un des autres. Pourriez-vous fournir le code pour une méthode que je pourrais appeler comme: 'NSRange (range, in: string)'? – ma11hew28