IconFont是啥?
我們通常看到的圖標都是以圖片形式集成到項目中使用,而 Iconfont 是一套字體圖標,和我們使用自定義字體的方式是一樣的,并且它是一種矢量圖標。
計算機中顯示的圖形一般分為兩類---位圖和矢量圖,我們平常使用的JPEG、PNG等圖片都是位圖格式,是一種由像素來表示的圖像,而矢量圖是由點、直線、多邊形等基于數學方程的幾何圖元表示的圖像,對比位圖,矢量圖具有體積小,放大縮小都不會失真的優點,這個優點就可以給項目帶來很大好處了,但缺點是無法用來表達色彩層次豐富的圖像,因此一些色彩復雜的圖形仍然需要位圖去表達。我們項目在進行模塊化碰到不同模塊使用到相同的圖片時,尤其是這種基礎icon,復制多份到各自的模塊中是不太優雅的,利用Iconfont就可以很好的解決。
IconFont的優點
圖片進行復用,并且很方便的更改圖片的大小和顏色。
減小應用體積,字體文件比圖片要小;
圖標保真縮放,解決2x/3x乃至將來nx圖問題;
同一套資源可以應用在不同的平臺 iOS,Android,web
IconFont的缺點
只是支持單色
制作成本高
在iOS中的使用姿勢
對于制作IconFont的流程和其他平臺的使用方式不做相關說明了,當前只說一下在iOS平臺的使用說明
1、IconFont的生成平臺,生成資源包
有很多的資源平臺,當然了也可以自己制作
打開demo_unicode.html
,我們可以看到Unicode碼和圖標之間的關系
2、導入到項目中
在Info.plist中進行配置,添加
Fonts provided by application
選項,添加進來的.ttf
文件名稱添加到數組中
3、在Label****中使用
使用方法和定制自定義的字體差不多。
首先要找到添加的.ttf對應的fontName的名稱。
最笨的方法就是直接獲取所有的字體,然后比較添加到plist之前和之后的字體有哪個不一樣,可以將兩次的打印結果放在Excel表格中進行對比。
NSArray*familyNames = [UIFont familyNames];
NSLog(@"familyNames.count === %ld",familyNames.count);
for(NSString*familyName in familyNames ){
printf("Family: %s \n", [familyName UTF8String]);
}
在Label中直接使用
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 60, 300, 50)];
// 字體使用下面對比出來的字體
label.font = [UIFont fontWithName:@"iconfont" size:35];
// 采用Unicode碼進行
label.text = @"下面展示的IconFont \U0000e77c \U0000e77d \U0000e781 \U0000e782 \U0000e787";
label.textColor = [UIColor orangeColor];
label.numberOfLines = 0;
[label sizeToFit];
[self.view addSubview:label];
顏色,大小可以隨便設置
4、在UIImage中使用
將文字轉化成圖片就可以了
相關代碼,封裝成了一個分類
#import <UIKit/UIKit.h>
@interface UIImage (IconFont)
/**
通過IconFont的形式創建圖片
* 例如 [UIImage imageWithIconFontName:@"iconfont" fontSize:100 text:@"\U0000e603" color:[UIColor greenColor]]
@param iconFontName iconFont的name
@param fontSize 字體的大小
@param text 文本信息<unicode>
@param color 顏色
@return 創建的圖片
*/
+ (UIImage *)imageWithIconFontName:(NSString *)iconFontName fontSize:(CGFloat)fontSize text:(NSString *)text color:(UIColor *)color;
@end
#import "UIImage+IconFont.h"
#import <CoreText/CoreText.h>
@implementation UIImage (IconFont)
/**
通過IconFont的形式創建圖片
@param iconFontName iconFont的name
@param fontSize 字體的大小
@param text 文案
@param color 顏色
@return 創建的圖片
*/
+ (UIImage *)imageWithIconFontName:(NSString *)iconFontName fontSize:(CGFloat)fontSize text:(NSString *)text color:(UIColor *)color
{
CGFloat size = fontSize;
CGFloat scale = [UIScreen mainScreen].scale;
CGFloat realSize = size * scale;
UIFont *font = [self fontWithSize:realSize withFontName:iconFontName];
UIGraphicsBeginImageContext(CGSizeMake(realSize, realSize));
CGContextRef context = UIGraphicsGetCurrentContext();
if ([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
*/
[text drawAtPoint:CGPointZero withAttributes:@{NSFontAttributeName:font, NSForegroundColorAttributeName:color}];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
CGContextSetFillColorWithColor(context, color.CGColor);
[text drawAtPoint:CGPointMake(0, 0) withFont:font];
#pragma clang pop
}
UIImage *image = [UIImage imageWithCGImage:UIGraphicsGetImageFromCurrentImageContext().CGImage scale:scale orientation:UIImageOrientationUp];
UIGraphicsEndImageContext();
return image;
}
/**
iconFont 轉化font
@param size 字體大小
@param fontName 字體的名稱
@return 字體的font
*/
+ (UIFont *)fontWithSize:(CGFloat)size withFontName:(NSString *)fontName {
UIFont *font = [UIFont fontWithName:fontName size:size];
if (font == nil) {
NSURL *fontFileUrl = [[NSBundle mainBundle] URLForResource:fontName withExtension:@"ttf"];
[self registerFontWithURL: fontFileUrl];
font = [UIFont fontWithName: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;
}
// 如果沒有在info.plist中聲明,在這注冊一下也可以。
+ (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);
}
@end
使用方法
UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(20, 350, 100, 100)];
imageView1.image = [UIImage imageWithIconFontName:@"iconfont" fontSize:80 text:@"\U0000e781" color:[UIColor greenColor]];
imageView1.layer.borderColor = [UIColor redColor].CGColor;
imageView1.layer.borderWidth = 1;
imageView1.contentMode = UIViewContentModeCenter;
[self.view addSubview:imageView1];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(20, CGRectGetMaxY(imageView1.frame)+20, 100, 50);
[btn setTitle:@"獅子" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn.layer.borderWidth = 1;
btn.layer.borderColor = [UIColor redColor].CGColor;
[self.view addSubview:btn];
UIImage *normalImage = [UIImage imageWithIconFontName:@"iconfont" fontSize:40 text:@"\U0000E784" color:[UIColor cyanColor]];
[btn setImage:normalImage forState:UIControlStateNormal];
如何支持一段文字中部分顏色不一樣?
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 60, CGRectGetWidth(self.view.frame)-20, 50)];
// 字體使用下面對比出來的字體
label.font = [UIFont fontWithName:@"iconfont" size:35];
NSString *showContent = @"下面展示的IconFont \U0000e77c \U0000e77d \U0000e781 \U0000e782 \U0000e787 \U0000eAAA787";
NSString *redShow = @"\U0000e77c";
NSString *yellowShow = @"\U0000e77d";
NSString *greenShow = @"\U0000e781";
NSString *cyanShow = @"\U0000e782";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:showContent];
// 改變文字顏色
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:[showContent rangeOfString:redShow]];
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor] range:[showContent rangeOfString:yellowShow]];
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:[showContent rangeOfString:greenShow]];
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor cyanColor] range:[showContent rangeOfString:cyanShow]];
// 采用Unicode碼進行
label.attributedText = attributedString;
label.numberOfLines = 0;
[label sizeToFit];
[self.view addSubview:label];
有啥更好的實現方法,或者有那個地方說的不對,歡迎指出。謝謝。