Answer the question of generosity
Here is an extension that allows you to build an NSAttributedString with a second set of attributes that will be applied to Latin characters:
extension String { private var englishRanges: [NSRange] { let set = NSMutableCharacterSet(range: NSRange(location: 0x0041, length: 26)) set.addCharactersInRange(NSRange(location: 0x0061, length: 26)) var start = startIndex var englishRanges = [Range<String.Index>]() while let range = rangeOfCharacterFromSet(set, options: [], range: start..<endIndex) { start = range.endIndex englishRanges.append(range) } return englishRanges.map {NSRange(location: startIndex.distanceTo($0.startIndex), length: $0.count)} } func attributedMultilanguageString(options: [String:AnyObject], englishOptions:[String:AnyObject]) -> NSAttributedString { let string = NSMutableAttributedString(string: self, attributes: options) englishRanges.forEach { string.setAttributes(englishOptions, range: $0) } return string } }
Usage example:
let font = UIFont(name: "Arial-BoldMT", size: 18.0)! let englishFont = UIFont(name: "Chalkduster", size: 18.0)! let label = UILabel() label.attributedText = "some string 111".attributedMultilanguageString([ NSFontAttributeName: font], englishOptions: [ NSFontAttributeName: englishFont])
Second approach
And this extension allows you to specify a fallback font instead of a second font for certain characters:
extension String { private func unsupportedCharacterIndexes(font: String) -> [String.Index] { let font = CGFontCreateWithFontName(font) return characters.indices.filter {CGFontGetGlyphWithGlyphName(font, String(self[$0])) == 0} } func attributedString(fontName: String, fallbackFontName: String, fontSize: CGFloat, options: [String:AnyObject]? = nil) -> NSAttributedString { var options = options ?? [String:AnyObject]() options[NSFontAttributeName] = UIFont(name: fontName, size: fontSize) let string = NSMutableAttributedString(string: self, attributes: options) options[NSFontAttributeName] = UIFont(name: fallbackFontName, size: fontSize) unsupportedCharacterIndexes(fontName).forEach { string.setAttributes(options, range: NSRange(location: startIndex.distanceTo($0), length: 1)) } return string } }
Usage example:
let label = UILabel() label.attributedText = "some ".attributedString("Chalkduster", fallbackFontName: "Baskerville-SemiBoldItalic", fontSize: 18)
bzz
source share