我正在为我的应用程序导航栏标题使用粗体自定义字体。
我刚刚将我的应用程序本地化。 对于字体不支持的语言(主要是亚洲语言),iOS将退回到系统默认字体 - 不幸的是,这不是粗体系统默认字体,而是标准字体,不适合用作标题。
我该怎么做才能改变这种情况?
我刚刚将我的应用程序本地化。 对于字体不支持的语言(主要是亚洲语言),iOS将退回到系统默认字体 - 不幸的是,这不是粗体系统默认字体,而是标准字体,不适合用作标题。
我该怎么做才能改变这种情况?
+ (UIFont *)addFallbacktoFont:(UIFont*)font{
UIFontDescriptor* originalDescriptor = [font fontDescriptor];
UIFontDescriptor* fallbackDescriptor = [originalDescriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorNameAttribute:@"Helvetica Neue"}];
UIFontDescriptor* repaired = [originalDescriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorCascadeListAttribute:@[
fallbackDescriptor
]}];
font = [UIFont fontWithDescriptor:repaired size:0.0];
return font;
}
回答赏金问题
这里有一个扩展,可以使用第二组属性构建NSAttributedString,该属性将应用于拉丁字符:
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
}
}
示例用法:
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])
第二种方法
这个扩展允许您指定替换字体,而不是为特定字符使用第二个字体:
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
}
}
示例用法:
let label = UILabel()
label.attributedText = "some текст".attributedString("Chalkduster", fallbackFontName: "Baskerville-SemiBoldItalic", fontSize: 18)
我不确定这是否是最好的方法,但我使用以下代码片段来检查特定语言:
//store all fallback languages in this array (eg.: el = greek, ru = russian)
NSArray *fallbackFont = @[@"el", @"ru"];
NSString *lang = [[NSLocale preferredLanguages] objectAtIndex:0]
BOOL hasFallbackFont = [fallbackFont containsObject:lang];
NSString *fontNameBold = hasFallbackFont ? @"Fallback-Font-Bold" : @"Regular-Font-Bold";
...
myLabel.font = [UIFont fontWithName:fontNameBold size:12.0];
基本上,如果语言不受支持,常规的if语句会替换自定义字体。换句话说,挑战在于找出所涉及的语言是否受支持。
解决方案可能不是最佳的,但我相信它应该有效:
CGFontRef cgFontVersion =
CGFontCreateWithFontName((CFStringRef)uiFont.fontName);
CGFontGetGlyphWithGlyphName
用于包含您计划支持的每种语言的必要字形的数组。CGFontGetGlyphWithGlyphName
返回0,则不支持您的自定义字体,您可以使用任何后备字体。*获取这些可能是最困难的部分,好的一面是,您只需要做一次即可,并且可以在将来的项目中再次使用...
更实用的解决方案是像Hannes建议的那样做,但是对于您决定在未来使用的每个新自定义字体,您都需要为每种语言手动重新执行此操作。
// Method that returns the font for buttons and title bar
// Pass in your custom font as a string argument/ parameter
func getFont(fontName: String, size fontSize: CGFloat)-> UIFont {
// Unwrap your custom font here, if font exists "Hooray!" else "Bo-Oh!" return a default one
if let customFont = UIFont(named: fontName, size: fontSize ) {
return customFont
} else {
// This gets the system default font and returns to you!
return UIFont(named: defaultFont, size: fontSize )
}
这样可以确保我们始终有一个可用的字体。现在,您可以从这里开始设置字体及其样式以获得首选视图/控件。
就这样了。请告诉我们您的使用情况如何!