Подтвердить что ты не робот

Могу ли я встроить собственный шрифт в пакет и получить доступ к нему из рамок ios?

Я создаю инфраструктуру ios с ее пакетом для упаковки ресурсов (nib, images, fonts), и я пытаюсь внедрить собственный шрифт в комплекте, но я не могу загрузить его из фреймворка, возможно ли это?

1) Я могу локализовать файл шрифта следующим образом: objc NSString *fontPath = [[NSBundle frameworkBundle] pathForResource:@"MyCustomFont" ofType:@"ttf"]; 2) Но я не могу получить его в своих списках шрифтов: objc NSArray * array = [UIFont familyNames]; Я включил свое имя шрифта в plest plist с "Шрифтами, предоставленными приложением", без успеха, также попробовал и в Info Info Plist, включив его в рамки ressource без успеха.

Я могу загрузить nib и изображения из пакета (путем префикса с именем пакета), но не для шрифта. Любая мысль?

EDIT: Я увидел следующее сообщение: Могу ли я встроить собственный шрифт в iPhone-приложение?, но вопрос просто "Могу ли я встроить собственный шрифт в приложение для iPhone?" а не "Могу ли я встроить собственный шрифт во внешнюю структуру/пакет?" Он также делает ссылки на динамическую загрузку, которая интересна, но использует частный api, который не является подходящим решением для фреймворка.

Спасибо

4b9b3361

Ответ 2

Вот как я это сделал для моего fmk на основе решения, предоставленного "Дэвидом М.", Это решение не требует добавления ссылки на шрифт в plist.

1) Класс, загружающий шрифт

- (void) loadMyCustomFont{
    NSString *fontPath = [[NSBundle frameworkBundle] pathForResource:@"MyFont" ofType:@"ttf"];
    NSData *inData = [NSData dataWithContentsOfFile:fontPath];
    CFErrorRef error;
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)inData);
    CGFontRef font = CGFontCreateWithDataProvider(provider);
    if (! CTFontManagerRegisterGraphicsFont(font, &error)) {
        CFStringRef errorDescription = CFErrorCopyDescription(error);
        NSLog(@"Failed to load font: %@", errorDescription);
        CFRelease(errorDescription);
    }
    CFRelease(font);
    CFRelease(provider);
}

2) Категория на NSBundle, чтобы получить доступ к моему пакету

+ (NSBundle *)frameworkBundle {
    static NSBundle* frameworkBundle = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath];
        NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:@"MyBundleName.bundle"];
        frameworkBundle = [NSBundle bundleWithPath:frameworkBundlePath];
    });
    return frameworkBundle;
}

Примечание: требуется интегрировать CoreText в ваш проект

Ответ 3

Swift 3:

Во-первых, не обращайтесь к базовому пакету из основного с добавлением компонентов пути... Создайте его из своего идентификатора. Вы можете получить URL-адреса шрифтов, например:

static func fontsURLs() -> [URL] {
    let bundle = Bundle(identifier: "com.company.project.framework")!
    let fileNames = ["Roboto-Bold", "Roboto-Italic", "Roboto-Regular"]
    return fileNames.map({ bundle.url(forResource: $0, withExtension: "ttf")! })
}

И мне приятно иметь расширение UIFont для регистрации шрифтов:

public extension UIFont {
    public static func register(from url: URL) throws {
        guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {
            throw SVError.internal("Could not create font data provider for \(url).")
        }
        let font = CGFont(fontDataProvider)
        var error: Unmanaged<CFError>?
        guard CTFontManagerRegisterGraphicsFont(font, &error) else {
            throw error!.takeUnretainedValue()
        }
    }
}

Теперь наслаждайтесь регистрацией:

do {
    try fontsURLs().forEach({ try UIFont.register(from: $0) })
} catch {
    print(error)
}

Ответ 4

В быстром, я использую следующий код:

public class func loadMyCustomFont(name:String) -> Bool{
  let fontPath = self.frameworkBundle().pathForResource(name, ofType: "ttf")!
  let inData = NSData(contentsOfFile:fontPath)
  var error: Unmanaged<CFError>?
  let provider = CGDataProviderCreateWithCFData(inData)
  if let font = CGFontCreateWithDataProvider(provider) {
     CTFontManagerRegisterGraphicsFont(font, &error)
     if error != nil {
       print(error) //Or logged it
       return false
     }


      }
       return true
   }

Метод frameworkBundle:

class func frameworkBundle() -> NSBundle{
       var bundle = NSBundle()
       var predicate = dispatch_once_t()
       dispatch_once(&predicate) {
          let mainBundlePath = NSBundle.mainBundle().bundlePath
          let frameworkBundlePath = mainBundlePath.stringByAppendingString("/myFramework.framework/")
          bundle = NSBundle(path: frameworkBundlePath)!
       }
       return bundle
 }

Пример вызова: (В моем случае я добавил все шрифты в папку Шрифты)

YouClassName.loadMyCustomFont("Fonts/Roboto-Regular")

Ваши исправления и замечания приветствуются!

Ответ 5

Swift 3 версия ответа @Ali-ABBAS, также обновленная до вариантов обертывания вместо развертывания силы.

fileprivate func loadCustomFont(name:String) -> Bool{

    guard let fontPath = frameworkBundle.path(forResource: name, ofType: "ttf") else {
        return false
    }

    guard let inData = NSData(contentsOfFile:fontPath) else {
        return false
    }


    guard let provider = CGDataProvider(data: inData) else {
        return false
    }

    let font = CGFont(provider)
    var error: Unmanaged<CFError>?
    CTFontManagerRegisterGraphicsFont(font, &error)
    guard error == nil else {
        print(error) //Or logged it
        return false
    }

    return true
}