iphone - font - ¿Cómo agrego una fuente personalizada a un Cocoapod?
install fonts on xcode (4)
Bueno, idk si puede ser una respuesta, pero también puede buscar Cocapez que ha necesitado una fuente, como esta: https://github.com/parakeety/GoogleFontsiOS
La biblioteca contiene muchas fuentes, necesitaba Chivo, así que agregué el pod ''GoogleFontsiOS / Chivo'' y lo usé en lugar de escribir el código de carga de fuentes por mi cuenta.
Quiero usar una fuente personalizada dentro de un Cocoapod, pero no puedo encontrar nada al usar una fuente personalizada dentro de una biblioteca estática. Como no hay un archivo info.plist, no hay dónde decirle a la aplicación qué fuente usar.
¿Algunas ideas?
Hay una forma de usar una fuente personalizada sin agregar nada al archivo plist.
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSURL *fontURL = [bundle URLForResource:<#fontName#> withExtension:@"otf"/*or TTF*/];
NSData *inData = [NSData dataWithContentsOfURL:fontURL];
CFErrorRef error;
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)inData);
CGFontRef font = CGFontCreateWithDataProvider(provider);
if (!CTFontManagerRegisterGraphicsFont(font, &error)) {
CFStringRef errorDescription = CFErrorCopyDescription(error);
NSLog(@"Failed to load font: %@", errorDescription);
CFRelease(errorDescription);
}
CFSafeRelease(font);
CFSafeRelease(provider);
También necesita la función CFSafeRelease
para que esto funcione.
void CFSafeRelease(CFTypeRef cf) {
if (cf != NULL) {
CFRelease(cf);
}
}
Fuente: Cargando fuentes iOS dinámicamente .
Swift equivalente:
extension UIFont {
static func registerFont(bundle: Bundle, fontName: String, fontExtension: String) -> Bool {
guard let fontURL = bundle.url(forResource: fontName, withExtension: fontExtension) else {
fatalError("Couldn''t find font /(fontName)")
}
guard let fontDataProvider = CGDataProvider(url: fontURL as CFURL) else {
fatalError("Couldn''t load data from the font /(fontName)")
}
guard let font = CGFont(fontDataProvider) else {
fatalError("Couldn''t create font from data")
}
var error: Unmanaged<CFError>?
let success = CTFontManagerRegisterGraphicsFont(font, &error)
guard success else {
print("Error registering font: maybe it was already registered.")
return false
}
return true
}
}
Para aquellos de ustedes que encontraron esto en 2018+, obtuve fuentes personalizadas para trabajar con el soporte del constructor de interfaces (XCode 9) con estos dos pasos:
Añade tus fuentes a un paquete de recursos
s.resource_bundles = { ''PodName'' => [''PodName/**/*.{ttf}''] }
Cargue fuentes en tiempo de ejecución utilizando la respuesta de Adán anterior.
#import <CoreText/CoreText.h> void CFSafeRelease(CFTypeRef cf) { // redefine this if (cf != NULL) { CFRelease(cf); } } + (void) loadFonts { NSBundle *frameworkBundle = [NSBundle bundleForClass:self.classForCoder]; NSURL *bundleURL = [[frameworkBundle resourceURL] URLByAppendingPathComponent:@"PodName.bundle"]; NSBundle *bundle = [NSBundle bundleWithURL:bundleURL]; NSURL *fontURL = [bundle URLForResource:@"HindMadurai-SemiBold" withExtension:@"ttf"]; NSData *inData = [NSData dataWithContentsOfURL:fontURL]; CFErrorRef error; CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)inData); CGFontRef font = CGFontCreateWithDataProvider(provider); if (!CTFontManagerRegisterGraphicsFont(font, &error)) { CFStringRef errorDescription = CFErrorCopyDescription(error); NSLog(@"Failed to load font: %@", errorDescription); CFRelease(errorDescription); } CFSafeRelease(font); CFSafeRelease(provider); }
Si entiendo correctamente, estás tratando de proporcionar una fuente con tu Cocoapod, e intentas las aplicaciones de iOS que incluyen el pod para poder usar tu fuente personalizada.
Este gancho post_install
parece funcionar:
Pod::Spec.new do |s|
# ...
s.resources = "Resources/*.otf"
# ...
s.post_install do |library_representation|
require ''rexml/document''
library = library_representation.library
proj_path = library.user_project_path
proj = Xcodeproj::Project.new(proj_path)
target = proj.targets.first # good guess for simple projects
info_plists = target.build_configurations.inject([]) do |memo, item|
memo << item.build_settings[''INFOPLIST_FILE'']
end.uniq
info_plists = info_plists.map { |plist| File.join(File.dirname(proj_path), plist) }
resources = library.file_accessors.collect(&:resources).flatten
fonts = resources.find_all { |file| File.extname(file) == ''.otf'' || File.extname(file) == ''.ttf'' }
fonts = fonts.map { |f| File.basename(f) }
info_plists.each do |plist|
doc = REXML::Document.new(File.open(plist))
main_dict = doc.elements["plist"].elements["dict"]
app_fonts = main_dict.get_elements("key[text()=''UIAppFonts'']").first
if app_fonts.nil?
elem = REXML::Element.new ''key''
elem.text = ''UIAppFonts''
main_dict.add_element(elem)
font_array = REXML::Element.new ''array''
main_dict.add_element(font_array)
else
font_array = app_fonts.next_element
end
fonts.each do |font|
if font_array.get_elements("string[text()=''#{font}'']").empty?
font_elem = REXML::Element.new ''string''
font_elem.text = font
font_array.add_element(font_elem)
end
end
doc.write(File.open(plist, ''wb''))
end
end
El gancho encuentra el proyecto del usuario, y en el primer objetivo (probablemente pueda completar esta solución pidiéndole a CocoaPods que le proporcione el objetivo real) busca sus archivos Info.plist
(normalmente solo hay uno). Finalmente, busca la clave UIAppFonts
del archivo, la crea si no se encuentra y llena la matriz con los nombres de las fuentes si aún no están allí.