I will like to provide the list of fonts that support the localised language. I could not find anything in UIFont and Font; but found something in CTFont and implemented the code below.
HOWEVER, I keep getting warnings like "CoreText note: Client requested name ".SFUI-BoldG4", it will get TimesNewRomanPSMT rather than the intended font. All system UI font access should be through proper APIs such as CTFontCreateUIFontForLanguage() or [UIFont systemFontOfSize:]."
Is there a better alternative in Swift to retrieve the system font list of a specific language?
import CoreText
import Foundation
import SwiftUI
extension CTFont {
func supportedLanguages(_ fontName: String, _ size: CGFloat = DEFAULT_USER_FONT_SIZE) -> [String] {
let font = CTFontCreateWithName(fontName as CFString, size, nil)
let languageIds = CTFontCopySupportedLanguages(font) as! [String]
return languageIds
}
}
extension UIFont {
static func supportedFontNames(language: String = "", size: CGFloat = DEFAULT_USER_FONT_SIZE) -> [String] {
var fontNames: [String] = []
for familyName in UIFont.familyNames {
for fontName in UIFont.fontNames(forFamilyName: familyName) {
if !fontNames.contains(fontName), CTFont(fontName as CFString, size: size).supportedLanguages(fontName, size).contains(language) {
fontNames.append(fontName)
}
}
}
return fontNames
}
}
CodePudding user response:
This can be more easily implemented using a CTFontCollection:
extension UIFont {
static func supportedFontNames(language: String) -> [String] {
// Create the query descriptor
let query = [kCTFontLanguagesAttribute: [language] as CFArray] as CFDictionary
let descriptor = CTFontDescriptorCreateWithAttributes(query)
// Perform the query and create a collection
let collection = CTFontCollectionCreateWithFontDescriptors([descriptor] as CFArray,
nil)
// Extract the name attributes
return CTFontCollectionCopyFontAttribute(collection,
kCTFontNameAttribute,
[]) as! [String]
}
}
CodePudding user response:
Thanks to answer Rob Napier's answer, I've now updated his solution to also support iOS14 below:
static func supportedFontNames(language: String) -> [String] {
// Create the query descriptor
let query = [kCTFontLanguagesAttribute: [language] as CFArray] as CFDictionary
let descriptor = CTFontDescriptorCreateWithAttributes(query)
// Perform the query and create a collection
let collection = CTFontCollectionCreateWithFontDescriptors([descriptor] as CFArray,
nil)
if #available(iOS 15.0, *) {
// Extract the name attributes
return CTFontCollectionCopyFontAttribute(collection,
kCTFontNameAttribute,
[]) as? [String] ?? []
} else {
var fontNames: [String] = []
if let fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors(collection) as? [CTFontDescriptor] {
fontNames = fontDescriptorArray.compactMap { descriptor -> String? in
return CTFontDescriptorCopyAttribute(descriptor, kCTFontNameAttribute) as? String
}
}
return fontNames
}
}