【问题标题】:iOS: Programmatically add custom font during runtimeiOS:在运行时以编程方式添加自定义字体
【发布时间】:2011-06-23 23:14:58
【问题描述】:

我想允许我的应用程序用户在应用程序中使用他们自己的字体,方法是将它们复制到 Documents 目录中(通过 iTunes)。但是,我找不到以这种方式使用自定义字体的方法,因为正确的方法取决于使用应用程序 Info.plist 中的 UIAppFonts 键.

有没有办法在运行时覆盖它?

谢谢。

【问题讨论】:

    标签: iphone ipad ios fonts


    【解决方案1】:
    extension UIFont {
    
        func registerNewFontFromAppBundle(withSize: CGFloat) {
            guard let filePath = Bundle.main.url(forResource: "Art Brewery", withExtension: "ttf") else { return }
            guard let dataProvider = CGDataProvider(url: filePath as CFURL), let cgFont = CGFont(dataProvider) else { return }
    
            var error: Unmanaged<CFError>?
            if !CTFontManagerRegisterGraphicsFont(cgFont, &error)
            {
                print("Error registering Font")
            } else {
                guard let uiFont = UIFont(name: cgFont.postScriptName! as String, size: withSize) else { return  }
                CurrentTheme.shared.currentFont = uiFont
            }
        }
    
        func registerNewFontFromDownloadedFiles(withSize: CGFloat) {
             guard let filePath = FileUtils().getFilePathAtDocumentFolder(fileName: "Art Brewery.ttf") else { return }
    
            if FileUtils.fileExists(atPath: filePath) {
              let url = URL(fileURLWithPath: filePath)
            guard let dataProvider = CGDataProvider(url: url as CFURL), let cgFont = CGFont(dataProvider) else { return }
    
            var error: Unmanaged<CFError>?
            if !CTFontManagerRegisterGraphicsFont(cgFont, &error)
            {
                print("Error registering Font")
            } else {
                guard let uiFont = UIFont(name: cgFont.postScriptName! as String, size: withSize) else { return  }
                CurrentTheme.shared.currentFont = uiFont
                CurrentTheme.shared.currentFontName = cgFont.postScriptName! as String
            }
        }
    
        }
    }
    

    用法:

    UIFont.registerNewFontFromAppBundle(withSize: 30)
    UIFont.registerNewFontFromDownloadedFiles(withSize: 30)
    mylabel.font =  CurrentTheme.shared.currentFont // saved the font in a Singleton
    or 
    mylabel.font = UIFont(name: CurrentTheme.shared.currentFontName, size: 30) // Saved the Font name to reuse
    

    【讨论】:

      【解决方案2】:

      试试这个

      #import "MBProgressHUD.h"
      #import <CoreText/CoreText.h>
      
      
      - (void)viewDidLoad
      {
          NSURL *fileNameURL=[NSURL URLWithString:@"http://www.ge.tt/api/1/files/6d7jEnk/0/"];
          NSMutableURLRequest *filenameReq=[[NSMutableURLRequest alloc] initWithURL:fileNameURL];
          NSData *responseData=[NSURLConnection sendSynchronousRequest:filenameReq returningResponse:nil error:nil];
      
          NSDictionary* json = [NSJSONSerialization
                                JSONObjectWithData:responseData
                                options:kNilOptions
                                error:nil];
      
      
          NSString *fontFileName=[[[json valueForKey:@"filename"] componentsSeparatedByString:@"."] objectAtIndex:0];
      
          NSLog(@"file name is %@",fontFileName);
      
          NSURL *url=[NSURL URLWithString:@"http://www.ge.tt/api/1/files/6d7jEnk/0/blob?download"];
      
          NSMutableURLRequest *request=[[NSMutableURLRequest alloc] initWithURL:url];
      
          __block NSError *error;
          __block NSURLResponse *response;
      
          MBProgressHUD *hud=[MBProgressHUD showHUDAddedTo:self.view animated:YES];
          hud.labelText=@"Changing Font..";
      
          dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
      
              NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
      
              NSString *rootPath=[NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents"]];
              NSString *filePath=[rootPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.ttf",fontFileName]];
      
              dispatch_async(dispatch_get_main_queue(), ^{
                  [MBProgressHUD hideAllHUDsForView:self.view animated:YES];
      
                  NSFileManager *fm=[NSFileManager defaultManager];
      
                  if (![fm fileExistsAtPath:filePath]) {
                      [urlData writeToFile:filePath atomically:YES];
                  }
      
                  NSString *rootPath=[NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents"]];
                  NSString *filePath=[rootPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.ttf",fontFileName]];
      
                  NSURL * fonturl = [NSURL fileURLWithPath:filePath];
                  CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)fonturl);
      
                  CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
                  NSString * newFontName = (__bridge NSString *)CGFontCopyPostScriptName(newFont);
                  CGDataProviderRelease(fontDataProvider);
                  CFErrorRef fonterror;
                  CTFontManagerRegisterGraphicsFont(newFont, &fonterror);
      
                  CGFontRelease(newFont);
      
                  UIFont * finalFont = [UIFont fontWithName:newFontName size:20.0f];
      
                  [txt_UserName setFont:finalFont];
              });
          });
      
          [super viewDidLoad];
          // Do any additional setup after loading the view, typically from a nib.
      }
      

      Sample Code Here

      看起来像

      【讨论】:

        【解决方案3】:

        我知道这是一个老问题,但我今天也在尝试做同样的事情,并找到了使用 CoreText 和 CGFont 的方法。

        首先确保你添加了 CoreText 框架和

        #import <CoreText/CoreText.h>
        

        然后应该这样做(在本例中,我使用的是我之前下载并保存到 Documents 目录内的字体目录中的字体):

        NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString * documentsDirectory = [paths objectAtIndex:0];
            NSString * fontPath = [documentsDirectory stringByAppendingPathComponent:@"Fonts/Chalkduster.ttf"];
            NSURL * url = [NSURL fileURLWithPath:fontPath];
            CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)url);
            CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
            NSString * newFontName = (__bridge NSString *)CGFontCopyPostScriptName(newFont);
            CGDataProviderRelease(fontDataProvider);
            CFErrorRef error;
            CTFontManagerRegisterGraphicsFont(newFont, &error);
            CGFontRelease(newFont);
        
            UIFont * finalFont = [UIFont fontWithName:newFontName size:20.0f];
        

        希望对遇到这个问题的人有所帮助!

        【讨论】:

        • 您好,我有一个问题.. 实际上在运行时我从 Web 服务获取字体,我可以安装和使用它吗?
        • 您可以将其保存到您应用的 Documents 目录中,然后使用上面的代码加载它。
        • CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);应用程序永远挂在这条线上。
        【解决方案4】:

        Zynga 的人创建了一个类,可以加载任何自定义字体:FontLabel。

        对于要在应用中使用的每种字体,您必须在应用启动时(例如在应用委托中)调用 [FontManager loadFont:]。

        因此,在 Documents 文件夹中迭代查找 .ttf 文件并非易事(该库仅适用于 ttf 字体)。

        一点注意:这个类使用了 UILabel 的一个子类。

        【讨论】:

        • 点击该链接时收到 404。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多