2015-05-15 16 views
20

Ho un riferimento a NSAttributedString e voglio modificare il testo della stringa attribuita.sostituisce l'intera stringa di testo in NSAttributoString senza modificare altri attributi

Suppongo di dover creare un nuovo NSAttributedString e aggiornare il riferimento con questa nuova stringa. Tuttavia quando faccio questo perdo l'attributo della stringa precedente.

NSAttributedString *newString = [[NSAttributedString alloc] initWithString:text]; 
[self setAttributedText:newString]; 

Ho riferimento alla vecchia stringa attribuita in self.attributedText. Come posso mantenere il precedente attribuito nella nuova stringa?

risposta

27

È possibile utilizzare NSMutableAttributedString e aggiornare semplicemente la stringa, gli attributi non cambieranno. Esempio:

NSMutableAttributedString *mutableAttributedString = [[NSMutableAttributedString alloc] initWithString:@"my string" attributes:@{NSForegroundColorAttributeName: [UIColor blueColor], NSFontAttributeName: [UIFont systemFontOfSize:20]}]; 

//update the string 
[mutableAttributedString.mutableString setString:@"my new string"]; 
20

versione Swift

Modificare il testo, mantenendo gli attributi:

let myString = "my string" 
let myAttributes = [NSForegroundColorAttributeName: UIColor.blue, NSFontAttributeName: UIFont.systemFont(ofSize: 40)] 
let mutableAttributedString = NSMutableAttributedString(string: myString, attributes: myAttributes) 

let myNewString = "my new string" 
mutableAttributedString.mutableString.setString(myNewString) 

I risultati per mutableAttributedString sono

  • enter image description here
  • enter image description here

Note

qualsiasi sottointervallo di attributi oltre indice 0 vengono scartati. Ad esempio, se si aggiunge un altro attributo per l'ultima parola della stringa originale, si è perso dopo che ho cambiato la stringa:

// additional attribute added before changing the text 
let myRange = NSRange(location: 3, length: 6) 
let anotherAttribute = [ NSBackgroundColorAttributeName: UIColor.yellow ] 
mutableAttributedString.addAttributes(anotherAttribute, range: myRange) 

Risultati:

  • enter image description here
  • enter image description here

Da questo possiamo vedere che la nuova stringa ottiene qualunque sia l'indice 0 della stringa originale.Infatti, se regolare l'intervallo di essere

let myRange = NSRange(location: 0, length: 1) 

otteniamo

  • enter image description here
  • enter image description here

Vedi anche

2

Questo è il modo con Objective-C (testato su iOS 9)

NSAttributedString *primaryString = ...; 
NSString *newString = ...; 

//copy the attributes 
NSDictionary *attributes = [primaryString attributesAtIndex:0 effectiveRange:NSMakeRange(primaryString.length-1, primaryString.length)]; 
NSMutableAttributedString *newString = [[NSMutableAttributedString alloc] initWithString:newString attributes:attributes]; 
NSMutableAttributedString *primaryStringMutable = [[NSMutableAttributedString alloc] initWithAttributedString:primaryString]; 

//change the string 
[primaryStringMutable setAttributedString::newString]; 

primaryString = [NSAttributedString alloc] initWithAttributedString:primaryStringMutable]; 

Controllare i riferimenti più importanti: attributesAtIndex:effectiveRange: e setAttributedString:.

1

La risposta di Darius è quasi arrivata. Contiene un errore minore. La corretta è:

Questo è il modo con Objective-C (testato su iOS 10)

NSAttributedString *primaryString = ...; 
NSString *newString = ...; 

//copy the attributes 
NSRange range = NSMakeRange(primaryString.length-1, primaryString.length); 
NSDictionary *attributes = [primaryString attributesAtIndex:0 effectiveRange:&range]; 
NSMutableAttributedString *newString = [[NSMutableAttributedString alloc] initWithString:newString attributes:attributes]; 
NSMutableAttributedString *primaryStringMutable = [[NSMutableAttributedString alloc] initWithAttributedString:primaryString]; 

//change the string 
[primaryStringMutable setAttributedString::newString]; 

primaryString = [NSAttributedString alloc] initWithAttributedString:primaryStringMutable]; 
1

Ho fatto un po 'di estensione per rendere questo veramente facile:

import UIKit 

extension UILabel { 
    func setTextWhileKeepingAttributes(string: String) { 
     if let newAttributedText = self.attributedText { 
      let mutableAttributedText = newAttributedText.mutableCopy() 

      mutableAttributedText.mutableString.setString(string) 

      self.attributedText = mutableAttributedText as? NSAttributedString 
     } 
    } 
} 

https://gist.github.com/wvdk/e8992e82b04e626a862dbb991e4cbe9c

+0

ho dovuto scrivere in questo modo: '(mutableAttributedText as AnyObject) .mutableString.setString (string) ' – Jonny

0

Per quelli di voi che lavorano con UIButtons, ecco una risposta migliorata basata su Wes's.

sembrava che l'aggiornamento di un etichetta di un tasto si era meglio essere fatto in questo modo:

let newtext = "my new text" 
myuibutton.setAttributedTitle(titlelabel.getTextWhileKeepingAttributes(string: newtext), for: .normal) 

Così ho finito con questa estensione:

import UIKit 

extension UILabel { 
    func setTextWhileKeepingAttributes(string: String) { 
     if let newAttributedText = self.attributedText { 
      let mutableAttributedText = newAttributedText.mutableCopy() 

      (mutableAttributedText as AnyObject).mutableString.setString(string) 

      self.attributedText = mutableAttributedText as? NSAttributedString 
     } 
    } 
    func getTextWhileKeepingAttributes(string: String) -> NSAttributedString { 
     if let newAttributedText:NSAttributedString = self.attributedText { 
      let mutableAttributedText = newAttributedText.mutableCopy() 

      (mutableAttributedText as AnyObject).mutableString.setString(string) 
      return mutableAttributedText as! NSAttributedString 
     } 
     else { 
      // No attributes in this label, just create a new attributed string? 
      let attributedstring = NSAttributedString.init(string: string) 
      return attributedstring 
     } 
    } 
} 
+0

non funziona, gli attributi sono scomparsi quando imposto una nuova stringa di testo per UILabel con l'uso di setTextWhileKeepingAttributes – user25

Problemi correlati