在iOS开发中使用iconfont图标

作者: 若锦 | 来源:发表于2016-06-29 15:49 被阅读11407次

    在开发iOS项目时,不可避免的会用到图标,而为了适配不同分辨率的设备,我们通常会需要@2x,@3x两套格式的图片,最明显的就是底部tabBar的图标使用。而对于那些有换肤需求的APP来说,还需要多套图来匹配不同的主题。通过切图的方式制作图标,一方面加大了开发者和设计者的工作量,另一方面也会增大APP的体积。而使用iconfont的可以达到以下目的
    1.减小应用体积,字体文件比图片要小;
    2.图标保真缩放,解决2x/3x乃至将来nx图问题;
    3.方便更改图标颜色大小,图片复用。

    所以为了给开发者、设计者稍微减少点工作量,给APP“减重,我们可以将iconfont应用到自己的项目中。那么,iconfont是怎么用的呢?iconfont,从字面上就能理解它就是字体,让开发者像使用字体一样使用图标。

    由于我是做开发的,所以对于iconfont的制作并不太熟悉,都是设计师做好了图标给我,如果你想学习iconfont的制作的话,可以去阿里巴巴的iconfont平台去看看,上面有比较全的资料。制作好的iconfont图标是一种.ttf格式的字体,如图:

    iconfont图标

    iconfont中的图标是这样的:

    iconfont中的图标

    而我们需要的是将.ttf格式的文件引入到自己的工程中

    接下来我们借助淘点点科技写的一个关于iconfont封装,方便我们使用iconfont。iconfont的封装包括


    iconfont

    1.TBCityIconInfo.h的实现

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface TBCityIconInfo : NSObject
    
    @property (nonatomic, strong) NSString *text;
    @property (nonatomic, assign) NSInteger size;
    @property (nonatomic, strong) UIColor *color;
    
    - (instancetype)initWithText:(NSString *)text size:(NSInteger)size color:(UIColor *)color;
    + (instancetype)iconInfoWithText:(NSString *)text size:(NSInteger)size color:(UIColor *)color;
    
    @end
    

    2.TBCityFontImageInfo.m的实现

    #import "TBCityIconInfo.h"
    
    @implementation TBCityIconInfo
    
    - (instancetype)initWithText:(NSString *)text size:(NSInteger)size color:(UIColor *)color {
        if (self = [super init]) {
            self.text = text;
            self.size = size;
            self.color = color;
        }
        return self;
    }
    
    + (instancetype)iconInfoWithText:(NSString *)text size:(NSInteger)size color:(UIColor *)color {
        return [[TBCityIconInfo alloc] initWithText:text size:size color:color];
    }
    
    @end
    

    3.TBCityIconFont.h的实现

    #import "UIImage+TBCityIconFont.h"
    #import "TBCityIconInfo.h"
    
    #define TBCityIconInfoMake(text, imageSize, imageColor) [TBCityIconInfo iconInfoWithText:text size:imageSize color:imageColor]
    
    @interface TBCityIconFont : NSObject
    
    + (UIFont *)fontWithSize: (CGFloat)size;
    + (void)setFontName:(NSString *)fontName;
    
    @end
    

    4.TBCityIconFont.m的实现

    #import "TBCityIconFont.h"
    #import <CoreText/CoreText.h>
    
    @implementation TBCityIconFont
    
    static NSString *_fontName;
    
    + (void)registerFontWithURL:(NSURL *)url {
        NSAssert([[NSFileManager defaultManager] fileExistsAtPath:[url path]], @"Font file doesn't exist");
        CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)url);
        CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
        CGDataProviderRelease(fontDataProvider);
        CTFontManagerRegisterGraphicsFont(newFont, nil);
        CGFontRelease(newFont);
    }
    
    + (UIFont *)fontWithSize:(CGFloat)size {
        UIFont *font = [UIFont fontWithName:[self fontName] size:size];
        if (font == nil) {
            NSURL *fontFileUrl = [[NSBundle mainBundle] URLForResource:[self fontName] withExtension:@"ttf"];
            [self registerFontWithURL: fontFileUrl];
            font = [UIFont fontWithName:[self fontName] size:size];
            NSAssert(font, @"UIFont object should not be nil, check if the font file is added to the application bundle and you're using the correct font name.");
        }
        return font;
    }
    
    + (void)setFontName:(NSString *)fontName {
        _fontName = fontName;
        
    }
    
    + (NSString *)fontName {
        return _fontName ? : @"iconfont";
    }
    
    @end
    

    5.UIImage+TBCityIconFont.h的实现

    #import <UIKit/UIKit.h>
    #import "TBCityIconInfo.h"
    
    @interface UIImage (TBCityIconFont)
    
    + (UIImage *)iconWithInfo:(TBCityIconInfo *)info;
    
    @end
    

    6.UIImage+TBCityIconFont.m

    #import "UIImage+TBCityIconFont.h"
    #import "TBCityIconFont.h"
    #import <CoreText/CoreText.h>
    
    @implementation UIImage (TBCityIconFont)
    
    + (UIImage *)iconWithInfo:(TBCityIconInfo *)info {
        CGFloat size = info.size;
        CGFloat scale = [UIScreen mainScreen].scale;
        CGFloat realSize = size * scale;
        UIFont *font = [TBCityIconFont fontWithSize:realSize];
        UIGraphicsBeginImageContext(CGSizeMake(realSize, realSize));
        CGContextRef context = UIGraphicsGetCurrentContext();
     
        if ([info.text respondsToSelector:@selector(drawAtPoint:withAttributes:)]) {
            /**
             * 如果这里抛出异常,请打开断点列表,右击All Exceptions -> Edit Breakpoint -> All修改为Objective-C
             * See: http://stackoverflow.com/questions/1163981/how-to-add-a-breakpoint-to-objc-exception-throw/14767076#14767076
             */
            [info.text drawAtPoint:CGPointZero withAttributes:@{NSFontAttributeName:font, NSForegroundColorAttributeName: info.color}];
        } else {
            
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
            CGContextSetFillColorWithColor(context, info.color.CGColor);
            [info.text drawAtPoint:CGPointMake(0, 0) withFont:font];
    #pragma clang pop
        }
        
        UIImage *image = [UIImage imageWithCGImage:UIGraphicsGetImageFromCurrentImageContext().CGImage scale:scale orientation:UIImageOrientationUp];
        UIGraphicsEndImageContext();
        
        return image;
    }
    
    @end
    
    

    7.在AppDelegate.m中,初始化我们的iconfont

    #import "AppDelegate.h"
    #import "TBCityIconFont.h"
    #import "ViewController.h"
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
       //iconfont图标
        [TBCityIconFont setFontName:@"iconfont"];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
        _window.rootViewController = nav;
        // Override point for customization after application launch.
        return YES;
    }
    
    

    8.在ViewController.m中实现

    #import "ViewController.h"
    #import "TBCityIconFont.h"
    #import "UIImage+TBCityIconFont.h"
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        self.navigationController.navigationBar.translucent = NO;
        
        UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc] initWithImage:[ UIImage iconWithInfo:TBCityIconInfoMake(@"\U0000e602",22,[UIColor colorWithRed:0.55 green:0.55 blue:0.55 alpha:1])] style:UIBarButtonItemStylePlain target:self action:@selector(leftButtonAction)];
        self.navigationItem.leftBarButtonItem = leftBarButton;
        
       
        self.navigationItem.leftBarButtonItem.tintColor = [UIColor colorWithRed:0.55 green:0.55 blue:0.55 alpha:1];
        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage iconWithInfo:TBCityIconInfoMake(@"\U0000e60d",25, [UIColor colorWithRed:0.14 green:0.61 blue:0.83 alpha:1.00])] style:UIBarButtonItemStylePlain target:self action:@selector(rightButtonAction)];
         self.navigationItem.rightBarButtonItem.tintColor = [UIColor colorWithRed:0.14 green:0.61 blue:0.83 alpha:1.00];
     
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    -(void)loadView{
        [super loadView];
    //    imageView
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 50, 30, 30)];
        [self.view addSubview:imageView];
    //图标编码是&#xe603,需要转成\U0000e603
        imageView.image = [UIImage iconWithInfo:TBCityIconInfoMake(@"\U0000e603", 30, [UIColor redColor])];
    //    button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        button.frame = CGRectMake(100, 100, 40, 40);
        [self.view addSubview:button];
        [button setImage:[UIImage iconWithInfo:TBCityIconInfoMake(@"\U0000e60c", 40, [UIColor redColor])] forState:UIControlStateNormal];
    //    label,label可以将文字与图标结合一起,直接用label的text属性将图标显示出来
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 160, 280, 40)];
        [self.view addSubview:label];
        label.font = [UIFont fontWithName:@"iconfont" size:15];//设置label的字体
        label.text = @"这是用label显示的iconfont  \U0000e60c";
    }
    -(void)leftButtonAction{
        
    }
    -(void)rightButtonAction{
        
    }
    

    9.运行得到的结果如图:

    iconfont图标示例

    这样,我们就可以很方便的使用iconfont图标了。这里要注意的是,图标是用的iconfont中的图标用的是unicode编码,我们在自己的工程中时需要将&#xXXXX格式转换成\UXXXXXXXX格式。

    demo地址

    相关文章

      网友评论

      • WangYeKun:我想知道字体或者主题是什么?觉得好看
        WangYeKun:@若锦 就是编码的主题或者字体
        若锦:@你还记得我 嗯?不太明白你意思:sweat_smile:
      • 小唐羽锋:这个怎么设置UITabBarItem
        若锦:@小唐羽锋 嗯,不也是设置image么
      • 小代码仔:你好。 在您的Demo项目中代码之上直接创建一个UILabel,设置label.text =@"\U0000e600" , 也是显示的问号。 但是,如果在您的代码下面同样的创建则会正常显示。您能给我解答下疑问么?
        若锦:@老秦__ 那不能呀,unicode 码对应上了就能正常显示,问号一般就是没找到这个图标,你再仔细看看图标的unicode 码是不是没对应上
        小代码仔:@若锦 设置了,比对了好多次
        若锦:@老秦__ 你是不是忘了将label的font设置成iconfont:joy:
      • iOS_:为什么我有些icon是问号
        若锦:@9e990c7f4f7b 不客气,问题解决了就好:joy:
        iOS_:@若锦 谢谢 你的回复 我解决了比较低级的错误
        若锦:@9e990c7f4f7b 是不是没对应正确的unicode码
      • iOS_tao:图片可以实现热更新不
        Unity与iOS的灵魂小白:作者发份demo给我呗 谢谢啦 328860643@qq.com
        若锦:@iOS_tao 这个不知道哟,没尝试过:fearful:
      • joymake:只能用unicode吗,
        joymake:@若锦 比如symbol 和fontclass
        joymake:@若锦 kaimen_big  比如这个我想用kaimen_big,不想用U00e62c
        若锦:@joymake 嗯?你是想用其他的什么:joy:
      • 994071fd5f29:想请问一下作者,可不可给我发一份源码,谢谢了
        邮箱:18297465491@163.com
        若锦:@xiaohujiazi 发过去了,你抽空查收一下哈:smile:
      • 阿飞_1217:有swift版的demo吗? 能发一下吗2511433510@qq.com。
        若锦:@阿飞_1217 不好意思,没有噢,没做swift的处理
      • 温暖的阳光_5353:很好用:smile:
        若锦:@温暖的阳光_5353 是的,项目一直用的它:joy:
      • 我的珊妮:设置后颜色成功了,可是图表变成一个问号是什么问题?
        若锦:@我的珊妮 应该是没找到这个图标,你看看你是不是把图标的Unicode码写错了,另外如果你是用的label显示图标的话是需要设置label的字体为iconfont的
      • _阿牛_:你好,咨询一下,设置图片的时候需要设置颜色,我们UI已经把图片做成彩色的了,不设置颜色就crash了
        若锦:@在路上_牛瑶 客户端需要设置颜色才有色彩的呢,所以你这边还是得设置对应的颜色才行
      • 程浩2016:多谢LZ,解决了问题,但调用时图片颜色设置不生效,要设image的模式为UIImageRenderingModeAlwaysOriginal,绘制的image我设了这个模式完美解决问题,return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];这样就OK了
      • 被吹落的风:怎么查看ttf文件里的图片呢,朋友
        若锦:@被吹落的风 会有一个unicode的html文件,你点那个文件就可以查看图片和对应的编码
      • 是我啊王同学:Nice
        若锦:@NWM thanks:blush:
      • 秀_ba75:为什么我下载下来的ttf文件,编码什么的都是对的。但是不可以用啊,就是一个打问号的图片
        若锦:@秀_ba75 你设置label字体的时候这样设置:label.font = [TBCityIconFont fontWithSize:14];
        秀_ba75:@若锦 设置了,就是不可以。我把你demo里的代码都注释了,就留那个lable的设置,会出现和我一样的情况,就一个问号的图片,你试试
        若锦:@秀_ba75 你设置了字体为iconfont 了不?
      • f630b11e7ccd:请问如何把多个图标转成一个字体文件实现啊
      • i_have_an_Apple:将XXXX格式转换成\UXXXXXXXX格式 怎么转,查了好多编码工具都不行
        若锦:@i_have_an_Apple 直接拼接\U0000
      • 清無: 是怎么转成 unicode的??
        清無:@若锦 解决了,多谢
        若锦:@若锦 制作图标的时候会有相应的unicode编码的,你可以看一下
        若锦:@菲拉兔 图标都有自己的unicode编码
      • 清無:不错
      • 147ecaddcb7e:楼主给分demo 看看谢谢3064697856@qq.com
        manajay:我这边UI做的图标有些都是一个色块 , 没有做好
        147ecaddcb7e:@若锦 好的,翻到底时看到了,谢谢,已经下载了
        若锦:嗯,已发送,请查收,其实文末有demo地址,有时候可能消息处理的没那么及时,可直接从github上下载:stuck_out_tongue_winking_eye:
      • 2cadf0a1a3f5:楼主可以发下demo给我吗?邮箱:306110597@qq.com
        若锦:嗯,已发送,请查收,其实文末有demo地址,有时候可能消息处理的没那么及时,可直接从github上下载:stuck_out_tongue_winking_eye:
      • 十秒_:楼主发一份demo给我呗 邮箱 759658182@qq.com
        若锦:@Feeeeeerny 发过去了哈,你查收一下:smile:
      • Huangbaoqin:iconfont上的图标不是居中的话,使用之后再ImageView上显示就会少掉一块 这个怎么解决
        若锦:你设置一下居中属性,看看好不好使,我没遇到这问题呢
      • 0792bc92b5c4:楼主 也发我一份呗 谢谢。875235563@qq.com
        0792bc92b5c4:@若锦 谢谢
        若锦:@never_小土豆 已发送,请抽空查收 :smile:
      • 18610b87c96b:楼主,需要一份源码,邮箱 1563145666@qq.com,谢谢
        若锦:@Originalpoint 已发送:smile:
      • LLVKS:可以给份demo吗?2961179785@qq.com 十分感谢
        若锦:@LLVKS 可以的,iconfont是矢量图,你换肤的时候是直接修改它的颜色就可以了吧:smile:
        LLVKS:@若锦 谢谢 对了 这个可以做换肤吗?如果可以是怎么做的呢?
        若锦:@LLVKS 已发送:smile:
      • fc06a2089061:请问我照着你这个思路,为何改变不了颜色呢》?急!!!
        若锦:@半瓶子 你是在什么控件上用的。你可以试试设置一下这个控件的tincolor
      • Fooler:大大,求demo!1025133834@qq.com
        Fooler:@若锦 嗯嗯,已收到,3Q
        若锦:@我是一朵向阳花 发过去了,你查收一下哈:smile:
      • kkkore:这个分享非常好。谢谢楼主。我已经搞定了。333Q :beers:
        若锦:@kkkore 厉害:smile:
      • kkkore:楼主还在吗。求一份demo~~ :pray:
      • kkkore:楼主,求一份demo。a09130414@163.com。谢谢~~ :+1:
      • f833411e4a26:非常感谢
      • f833411e4a26:楼主发一份demo给我呗 邮箱 wjiancheng1026@qq.com
        f833411e4a26:@若锦 已收到 谢谢啦
        若锦: @一日一生 嗯,已发送,你抽空查收下😀
        f833411e4a26:@一日一生 非常感谢
      • 横爬介士:楼主,demo的没有呀,有的话方便发一份么? tobecrabman@163.com。不胜感激
        若锦:@横爬介士 已经发送过去了,你抽空查收一下:smile:
      • 69baf91b8691:从哪里服装过来的,一个问题解决不了
        若锦: @nslog123 嗯?什么问题?
      • 赛赛_lzx:我知道怎么搞了~
      • 赛赛_lzx://图标编码是,需要转成\U0000e603 你这个图标编码是从哪里来的?我从阿里的库里下载了两个图标试试。
      • 红烧大鸡腿:可不可以弱弱地问一句为什么iconfont可以保真缩放?2x,3x乃至nx自动切换?用什么方法可以监测它的保真性? :smile:
        若锦:@HCX_IOS iconfont图标是矢量图标,你需要多大尺寸的就取多大的,它呢,可以说是一种特殊的字体,自己根据需求设置大小。不用去检测它的保真性的
      • AlexLi_:请问楼主是怎么把 XXXX格式转换成\UXXXXXXXX格式 的
        Unity与iOS的灵魂小白:@Cyandnow 没看懂啊 老哥
        pFruHMXB:一开始我也迷这里 希望可以帮到别人,并不是调用什么方法 就是把 "" 直接转换为 "\U0000" 就可以了.
        若锦:@CancerJing 你的图标字符串不是本地的?如果是本地的话直接拼接就可以,
      • 8d3e8c3e510c:你好,请问下可以提供下源码么
        若锦:@华少不思议 已发送:smile:
        开发界的白小白:@若锦 1312656992@qq.com

        若锦:@8d3e8c3e510c 嗯,需要的话可以留个联系方式 :smile:
      • 霊楓:接口返回的是XXXX格式,咋用代码转换成\UXXXXXXXX格式嘞??求教求教,字符串拼接和字符替换都不好使 :scream:
        若锦:@霊楓 我没太明白你的意思。你的图标是接口返回的字符串? :joy:
        霊楓:@霊楓 额...系统把那几个字符屏蔽了...就是文章最后的那个格式
        霊楓:@霊楓 少了几个字符,接口返回的是XXXX格式 :disappointed_relieved:
      • 751fc49dcbfd:2x 3x 自动适配?
        若锦:@1140752635 嗯嗯,是的
      • ff6250868c5d:没有加断点啊~还是这个错~
        2016-07-02 20:40:57.699 IconFontDemo[74137:3197958] *** Assertion failure in +[SDIconFont fontWithSize:], /Users/sandou/Desktop/IconFontDemo/IconFontDemo/SDIconFont.m:30
        2016-07-02 20:40:57.703 IconFontDemo[74137:3197958] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UIFont object should not be nil, check if the font file is added to the application bundle and you're using the correct font name.'
        东也_:文件名称只能是iconfont 如果要改名称 要到二进制文件里面改才行
        若锦:@sandouchan 你的iconfont的名字是怎样的,你这个错误是因为没有找到对应的图标
      • ff6250868c5d:不知道为什断言哪里老是报错~
        若锦: @sandouchan 你的工程里加了断点,你把断点去了就可以了
      • 帅气的华子:不错
        若锦:@帅气的华子 谢谢:stuck_out_tongue:
      • 春泥Fu:你好,我想问下iconfont中的图标,制作的话会麻烦吗?能不能上传个图片,自动生成相应的文字。
        若锦:@春泥Fu 哈哈,不用客气:stuck_out_tongue:
        春泥Fu:@若锦 好哒~谢谢啦
        若锦:@春泥Fu 嗯,制作的话不是很麻烦的,你将选好的图标上传就可以,图标会有自己对应的unicode编码的。不过具体的制作流程我没接触过,你可以去网上找找资料:joy::joy:我这边的iconfont图标是设计师找的
      • 晴天等不到你:6到不行
        若锦:@晴天等不到你 哈哈,这个确实非常方便:smiley::smiley:公司项目中图标就是用的iconfont,真的很好用

      本文标题:在iOS开发中使用iconfont图标

      本文链接:https://www.haomeiwen.com/subject/btkxjttx.html