2015-10-04 30 views
9

Sto tentando di determinare gli indici di occorrenze di una data stringa in un String, quindi generare un NSRange utilizzando tali indici al fine di aggiungere attributi a un NSMutableAttributedString. Il problema è rangeOfString restituisce Range<Index> ma addAttributes:range: prevede uno NSRange. I miei tentativi di creare un NSRange dagli indici di inizio e fine dello Range non sono riusciti, perché String.CharacterView.Index non è un Int, quindi non verrà compilato.Usando gamma <Index> con NSRange nell'API NSAttributedString

Come utilizzare i valori Range<Index> per creare un NSRange?

var originalString = "Hello {world} and those who inhabit it." 

let firstBraceIndex = originalString.rangeOfString("{") //Range<Index> 
let firstClosingBraceIndex = originalString.rangeOfString("}") 

let range = NSMakeRange(firstBraceIndex.startIndex, firstClosingBraceIndex.endIndex) 
//compile time error: cannot convert value of type Index to expected argument type Int 

let attributedString = NSMutableAttributedString(string: originalString) 
attributedString.addAttributes([NSFontAttributeName: boldFont], range: range) 
+0

Non vedo che chiami 'rangeOfString 'ovunque. Il tuo codice non ha senso. Che diamine è 'originalString (" {")' ???? Questo non può essere il tuo vero codice; è un'assurdità. – matt

+0

@matt Manca una parte della seconda e della terza riga, aggiornata – Joey

+0

La mia risposta rimane la stessa. Dove ora hai 'let firstBraceIndex = originalString.rangeOfString (" {")', dì 'let firstBraceIndex = (originalString as NSString) .rangeOfString (" {")'. Ora hai un NSRange e puoi continuare da lì. – matt

risposta

8

Se si inizia con la stringa originale lanciato come un cacao NSString:

var originalString = "Hello {world} and those who inhabit it." as NSString 

... poi i risultati gamma sarà NSRange e sarete in grado di mano di nuovo al cacao.

+0

E guarda il mio libro, che approfondisce questo argomento in dettaglio: http://www.apeth.com/swiftBook/ch03.html#_string – matt

+0

Non c'è modo di farlo con una stringa Swift nativa? – Joey

+0

Questo è il modo per farlo con una stringa nativa Swift. Non vedo cosa stai cercando. Ho risolto il problema per te. Hai bisogno che io riscrivi tutto il tuo codice e lo provi? Prova solo quello che ho detto. – matt

4

Per creare un NSRange è necessario ottenere la posizione iniziale e la lunghezza dell'intervallo come ints. È possibile farlo utilizzando il metodo distance(from:to:) sul originalString:

let rangeStartIndex = firstBraceIndex!.lowerBound 
let rangeEndIndex = firstClosingBraceIndex!.upperBound 

let start = originalString.distance(from: originalString.startIndex, to: rangeStartIndex) 
let length = originalString.distance(from: rangeStartIndex, to: rangeEndIndex) 

let nsRange = NSMakeRange(start, length) 

let attributedString = NSMutableAttributedString(string: originalString) 
attributedString.addAttributes([NSFontAttributeName: boldFont], range: nsRange) 

Per ottenere lo startingLocation, ottenere la distanza dal 's del originalString startIndex, l'indice di partenza della gamma che si desidera (che nel tuo caso sarebbe lo firstBraceIndex.lowerBound se si desidera includere { o firstBraceIndex.upperBound in caso contrario. Quindi per ottenere la lunghezza del tuo intervallo, prendi la distanza dall'indice iniziale del tuo intervallo al suo indice finale.

Ho appena forzato il tuo codice firstBraceIndex e firstClosingBraceIndex per rendere il codice più facile da leggere, ma ovviamente sarebbe meglio trattare correttamente questi potenzialmente essendo nulli.