2015-12-28 10 views
6

В последнее время я пытаюсь применить комбинации NSFontAttributes к NSMutableAttributedString, и я просто не могу найти подробное объяснение, как это сделать, не удаляя другие атрибуты.Как применить жирный и курсив к диапазону NSMutableAttributedString?

Я никогда искал кучу, и нашел этот question, относящихся к тому, как сделать это с HTML, а затем это question о том, как найти где текст был жирным шрифтом или курсивом, но ничего о том, как на самом деле это сделать ,

В настоящее время я пытаюсь укусы формат следующим образом:

Курсив: [mutableAttributedString addAttribute: NSFontAttributeName value:[fontAttributes valueForKey:CXItalicsFontAttributeName] range:r];

Жирный:[mutableAttributedString addAttribute:NSFontAttributeName value:[fontAttributes valueForKey:CXBoldFontAttributeName] range:r];

Где константы CXItalicsFontAttributeName и CXBoldAttributeName извлечь следующие два значения из словарь с уважением:

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

Я знаю, что это не должно быть правильным способом для форматирования, поскольку NSAttributedString standard attributes не включает в себя атрибут ItalicsFontAttribute или BoldFontAttribute, но я не могу найти правильный способ сделать это. Может ли кто-нибудь помочь мне?

ответ

4

Если вы применяете каждый (полужирный или курсивный) признак индивидуально, вам необходимо убедиться, что полужирный и курсивные диапазоны не перекрываются, или одна черта будет перезаписывать другую.

Единственный способ применить оба полужирных и курсивом к диапазону - использовать шрифт, выделенный полужирным шрифтом и курсивом, и применить оба свойства одновременно.

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

Этот метод кажется непрактичным. Это означает, что мне нужно будет создать как можно больше комбинаций, чтобы попытаться учитывать все случаи. Я надеялся избежать этого. – Micrified

+0

@Owatch Здесь [вопрос, который спрашивает о перечислении] (http://stackoverflow.com/q/14161254/4151918). Вам все равно нужно будет создавать шрифты «на лету». Это не так. –

+0

Я выбрал ваш ответ в качестве решения раньше, поскольку я не мог найти альтернативы, но с тех пор нашел что-то более подходящее для того, что я искал, поэтому я удалил галочку. Прошу прощения за непоследовательность. – Micrified

4

Лучшее решение моей проблемы до сих пор, чтобы использовать UIFontDescriptor класса предоставить мне необходимую UIFont для каждого случая я сталкиваюсь.

Например, как я хочу использовать Avenir-Book в качестве основного шрифта с размером 14, я могу создать UIFontDescriptor следующим образом:

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

Далее, если я хочу получить Курсив, Bolded, или комбинация обоих, я просто сделать следующее:

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]; 

И это действительно производит необходимые шрифты при печати:

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); 

Выход:

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

Преимущество здесь является то, что я больше не нужно создавать индивидуальные типы шрифтов сам, и шрифт из семейства достаточно, чтобы сделать это.

3

В Свифта и с использованием расширения:

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 ]) 
    } 
} 

Пример:

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()) ]) 
}