2015-05-15 15 views
20

Mam odwołanie do NSAttributedString i chcę zmienić tekst zaszyfrowanego ciągu.Zastąp cały ciąg tekstowy w NSAttributedString bez modyfikowania innych atrybutów

Domyślam się, że muszę utworzyć nowy NSAttributedString i zaktualizować referencję o ten nowy ciąg. Jednak gdy to zrobię, tracę przypisany poprzedni ciąg.

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

Mam odniesienie do starego atrybutu string w self.attributedText. Jak mogę zachować poprzednie przypisane w nowym ciągu?

Odpowiedz

27

Można użyć NSMutableAttributedString i po prostu zaktualizować ciąg, atrybuty nie ulegną zmianie. Przykład:

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

Swift wersja

zmienić tekst, zachowując atrybuty:

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) 

wyników dla mutableAttributedString

  • enter image description here
  • enter image description here

Uwagi

Wszelkie podzakresy atrybutów poza indeksem 0 są odrzucane. Na przykład, jeśli mogę dodać kolejny atrybut do ostatniego słowa oryginalnego łańcucha, to traci się po tym, jak zmienić ciąg:

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

wyniki:

  • enter image description here
  • enter image description here

Z tego widać, że nowy ciąg otrzymuje wszystkie atrybuty z indeksu 0 oryginalnego łańcucha.Rzeczywiście, jeśli dostosować zakres być

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

otrzymujemy

  • enter image description here
  • enter image description here

Zobacz także

2

W ten sposób za pomocą celem C (testowane na 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]; 

Sprawdź ważniejszych publikacji: attributesAtIndex:effectiveRange: i setAttributedString:.

1

Odpowiedź Dariusa już prawie. Zawiera niewielki błąd. Poprawna jest:

ten sposób przy użyciu Objective-C (testowane na 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

Zrobiłem małe rozszerzenie, aby to naprawdę proste:

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

muszę napisać tak: '(mutableAttributedText jako AnyObject) .mutableString.setString (ciąg) ' – Jonny

0

Dla tych, którzy pracują z UIButtons, tutaj jest poprawiona odpowiedź na podstawie Wes's.

Wydawało się, że aktualizowanie etykietę przycisku lepiej to zrobić w ten sposób:

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

więc skończyło się z tego rozszerzenia:

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

nie działa, atrybuty zniknęły, gdy ustawiłem nowy ciąg tekstowy dla UILabel z użyciem setTextWhileKeepingAttributes – user25

Powiązane problemy