2015-12-28 20 views
6

Ho cercato di applicare combinazioni di NSFontAttributes a NSMutableAttributedString ultimamente e semplicemente non riesco a trovare una spiegazione approfondita su come farlo senza rimuovere altri attributi.Come applicare grassetto e corsivo in un intervallo NSMutableAttributoStringa?

Ho cercato un mazzo, e abbiamo trovato questo question pertinenza di come farlo con HTML, e poi questo question su come trovare in cui il testo è stato in grassetto o in corsivo, ma nulla su come farlo in realtà .

Attualmente, cerco di punture di formato come segue:

corsivo: [mutableAttributedString addAttribute: NSFontAttributeName value:[fontAttributes valueForKey:CXItalicsFontAttributeName] range:r];

Bold:[mutableAttributedString addAttribute:NSFontAttributeName value:[fontAttributes valueForKey:CXBoldFontAttributeName] range:r];

Dove le costanti CXItalicsFontAttributeName e CXBoldAttributeName estrarre i seguenti due valori da un dizionario rispettosamente:

UIFont *italicsFont = [UIFont fontWithName:@"Avenir-BookOblique" size:14.0f]; 
UIFont *boldFont = [UIFont fontWithName:@"Avenir-Heavy" size:14.0f]; 

So che questo non deve essere il modo giusto per andare sulla formattazione, poiché la NSAttributedString standard attributes non include un ItalicsFontAttribute o BoldFontAttribute, ma non riesco a trovare il modo corretto per farlo. Qualcuno può aiutarmi?

risposta

4

Se si applicano i tratti (in grassetto o in corsivo) singolarmente, è necessario assicurarsi che gli intervalli in grassetto e in corsivo non si sovrappongano o che un tratto sovrascriva l'altro.

L'unico modo per applicare entrambi i tratti corsivi in ​​grassetto e in corsivo è utilizzare un carattere che è sia in grassetto che in corsivo e applicare entrambi i tratti contemporaneamente.

let str = "Normal Bold Italics BoldItalics" 

let font = UIFont(name: "Avenir", size: 14.0)! 
let italicsFont = UIFont(name: "Avenir-BookOblique", size: 14.0)! 
let boldFont = UIFont(name: "Avenir-Heavy", size: 14.0)! 
let boldItalicsFont = UIFont(name: "Avenir-HeavyOblique", size: 14.0)! 

let attributedString = NSMutableAttributedString(string: str, attributes: [NSFontAttributeName : font]) 
attributedString.addAttribute(NSFontAttributeName, value: boldFont, range: NSMakeRange(7, 4)) 
attributedString.addAttribute(NSFontAttributeName, value: italicsFont, range: NSMakeRange(12, 7)) 
attributedString.addAttribute(NSFontAttributeName, value: boldItalicsFont, range: NSMakeRange(20, 11)) 

enter image description here

+0

Questo metodo sembra poco pratico. Significa che dovrò creare il maggior numero di combinazioni possibili per cercare di tenere conto di tutti i casi. Speravo di evitarlo. – Micrified

+0

@Owatch Ecco [una domanda che chiede di enumerare] (http://stackoverflow.com/q/14161254/4151918). Avrai comunque bisogno di costruire i caratteri al volo. Non c'è modo di aggirare questo. –

+0

Avevo scelto la risposta come soluzione prima perché non riuscivo a trovare alternative, ma da allora ho trovato qualcosa di più adatto a quello che stavo cercando, così ho rimosso il segno di spunta. Mi scuso per essere incoerente. – Micrified

4

La migliore soluzione al mio problema finora è stato quello di utilizzare la classe di UIFontDescriptor di fornire me con la necessaria UIFont per ogni caso che incontro.

Per esempio, come io voglio usare Avenir-Book come il mio carattere primaria con dimensioni 14, posso creare un UIFontDescriptor come segue:

UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:@"Avenir-Book" size:14.0f];

Avanti, se voglio ottenere il Corsivo, grassetto, o una combinazione di entrambi, devo semplice da fare come segue:

NSString *normalFont = [[fontDescriptor fontAttributes]valueForKey:UIFontDescriptorNameAttribute]; 
NSString *italicsFont = [[[fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic]fontAttributes]valueForKey:UIFontDescriptorNameAttribute]; 
NSString *boldFont = [[[fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold]fontAttributes]valueForKey:UIFontDescriptorNameAttribute]; 
NSString *boldAndItalicsFont = [[[fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold | UIFontDescriptorTraitItalic]fontAttributes]valueForKey:UIFontDescriptorNameAttribute]; 

e questo produce effetti i font necessari in fase di stampa:

NSLog(@"Normal Font: %@ Size: %@\n",normalFont,[[fontDescriptor fontAttributes]valueForKey:UIFontDescriptorSizeAttribute]); 
NSLog(@"Italics Font: %@\n",italicsFont); 
NSLog(@"Bold Font: %@\n",boldFont); 
NSLog(@"Bold and Italics Font: %@\n",boldAndItalicsFont); 

uscita:

Normal Font: Avenir-Book Size: 14 
Italics Font: Avenir-BookOblique 
Bold Font: Avenir-Black 
Bold and Italics Font: Avenir-BlackOblique 

Il vantaggio è che non ho più bisogno di creare i singoli tipi di font me stesso, e un fonte della famiglia è sufficiente per farlo.

3

In Swift e con un'estensione:

extension UIFont { 

    func withTraits(_ traits: UIFontDescriptorSymbolicTraits) -> UIFont { 

     // create a new font descriptor with the given traits 
     if let fd = fontDescriptor.withSymbolicTraits(traits) { 
      // return a new font with the created font descriptor 
      return UIFont(descriptor: fd, size: pointSize) 
     } 

     // the given traits couldn't be applied, return self 
     return self 
    } 

    func italics() -> UIFont { 
     return withTraits(.traitItalic) 
    } 

    func bold() -> UIFont { 
     return withTraits(.traitBold) 
    } 

    func boldItalics() -> UIFont { 
     return withTraits([ .traitBold, .traitItalic ]) 
    } 
} 

Esempio:

if let font = UIFont(name: "Avenir", size: 30) { 
    let s = NSAttributedString(string: "Hello World!", attributes: [ NSFontAttributeName: font.italic() ]) 
    let t = NSAttributedString(string: "Hello World!", attributes: [ NSFontAttributeName: font.boldItalic()) ]) 
} 
Problemi correlati