iOS开发基础:自定义UILabel

题图

UILabel是一种文本视图,支持显示一行或多行的只读文本,算是大家的常用视图类,不过虽然用得多,同样的效果,用了很多不同方法,时间久了,难免有些混淆疑惑,本篇从以下几个方面做一个归纳总结:

  1. 自定义字体
  2. 制作不规则的边框
  3. 显示不同字体和颜色
  4. 调整缩进与行距

如本文题图这样的标题,就是使用以上四步编码出来的,下面将逐步介绍实现它。

1. 自定义字体

iOS9系统里,系统默认的中文字体是“苹方”,虽然是很优雅的中文字体,不过爱天马行空的UI设计美眉一定不会满足,总是爱找“最美”的字体来搭配她们的设计,iOS系统中往往没有这些字体,这时候怎么办呢?

步骤一:找到UI效果图中的字体文件

字体文件术语称为矢量字库,一般是以TTF结尾的,你可以请教UI设计美眉:“请问,你这幅效果图某某位置用的是什么字体呀?”(多好的搭讪机会),比如本文题图中“自定义”三个字用的是“方正正纤黑”这款字体,这时有经验的设计美眉一定会把TTF文件传给你,这里假设就是方正正纤黑.TTF,双击该文件用字体册查看,记录下显示的字体名称FZZhengHeiS-EL-GB,后面会用到。

查看字体名称

步骤二:将TTF文件导入Xcode工程

拖入TTF文件

注意接下来的导入选项,特别Add to targets千万不能漏选,否则后面的将导致后面的步骤失败:
导入文件选项

步骤三:在plist文件中添加配置

配置plist文件

添加Fonts provided by application,点击Item 0的Value栏,填入方正正纤黑.TTF注意 这里的名字与步骤二导入的TTF文件的文件名一致

步骤四:查看系统加载的字体

在任意m文件,运行以下代码:

// 获取系统字体名称:
for(NSString *fontfamilyname in [UIFont familyNames]) {
  NSLog(@"family:'%@'",fontfamilyname);
  for (NSString *fontName in [UIFont fontNamesForFamilyName:fontfamilyname]) {
    NSLog(@"\\\\tfont:'%@'",fontName);
  }
    NSLog(@"-------------");
}
// Swift 版
for fontfamilyname in UIFont.familyNames {
            print("family:" + fontfamilyname)
            
            for fontName in UIFont.fontNames(forFamilyName: fontfamilyname) {
                print("\\\\tfont:" + fontName)
            }
            print("-------------")
        }

这段代码遍历了当前iOS系统安装的全部字体,在输出控制台查找(快捷键⌘F)步骤一最后查出的字体名称FZZhengHeiS-EL-GB,复制font:后面的FZZXHJW--GB1-0,这才是最后我们要用的字体名称。

如果这里查找不到自己导入的字体名称,说明步骤二导入选项没有正确勾选,删除项目中的TTF文件,重做步骤二。

步骤五:使用导入的字体

UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, w, h)];
[self.view addSubview:aLabel];
aLabel.text = @"自定义UILabel";
aLabel.textAlignment = NSTextAlignmentCenter; // 设置文字对齐方式为居中
aLabel.textColor = [UIColor whiteColor]; // 设置文字颜色为白色
aLabel.font = [UIFont fontWithName:@"FZZXHJW--GB1-0" size:25];

这样我们就初步使用了自定义的字体代替了系统默认字体。

使用自定义字体最终效果

2. 制作不规则的边框

提起圆角矩形,很多iOS开发者脑子里立刻浮现的是UIView的layer属性:

view.layer.cornerRadius = 5

但是遇到如题图中这样需要指定哪一个角为圆角的效果,layer并没有对应的属性,这里我们就需要使用CALayer的一个子类CAShapeLayer,直接来看代码:

    //定义路径参数:
    CGRect rect = CGRectMake(0, 0, w, h);
    CGSize radii = CGSizeMake(20, 20); // 定义原角大小
    UIRectCorner corners = UIRectCornerTopLeft | 
                           UIRectCornerBottomRight; // 标记左上和右下为圆角
    
    //创建路径,这里使用贝塞尔曲线
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];
    
    //创建CAShapeLayer
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.fillColor = [UIColor clearColor].CGColor;//RGBA(169, 252, 121, 0.5).CGColor;
    shapeLayer.strokeColor = RGBA(169, 252, 121, 0.8).CGColor; // 设置线条的颜色
    shapeLayer.lineWidth = 6;
    shapeLayer.lineJoin = kCALineJoinRound;
    shapeLayer.lineCap = kCALineCapRound;
    shapeLayer.path = path.CGPath; // 指定前面设置好path

    // 将创建好的CAShapeLayer添加为UILabel的子layer
    [aLabel.layer addSublayer:shapeLayer];
自定义的边框效果

3. 显示不同字体和颜色

aLabel.text 是大家常用来配置实际文字的属性,配合font属性,我们只能设置全部文字为一个字体,如果需要为自定义UILabel指定不同的字体,有些新手就会定义两个Label,将这个问题转换为两个Label位置的拼凑,这里介绍UILabel自带的attributedText属性,比使用多个Label在视图适配上有很大的优势。

// 创建NSMutableAttributedString
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString: @"自定义UILabel\\n 溪石 "];
// 设置文字颜色
[str addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, 3)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(3, 8)];
// 设置阴影
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor darkGrayColor];
shadow.shadowOffset = CGSizeMake(2.0f, 2.0f);
[str addAttribute:NSShadowAttributeName value:shadow range:NSMakeRange(0, 10)];
// 设置文字颜色
[str addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(11, 4)];
// 设置背景颜色
[str addAttribute:NSBackgroundColorAttributeName value:[UIColor orangeColor] range:NSMakeRange(11, 4)];
// 指定字体,这里使用了三种字体
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"FZZXHJW--GB1-0" size:28.0] range:NSMakeRange(0, 3)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:28.0] range:NSMakeRange(3, 8)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Light" size:20.0] range:NSMakeRange(11, 4)];
// 将配置好的NSMutableAttributedString传给attributedText属性
aLabel.attributedText = str;

注意,使用attributedText属性后,原text属性将被忽略。

分别设置字体和颜色

4. 调整缩进与行距

运行后可以看见,字体和颜色被区分开来,还加上了阴影效果,不过发现问题了吗?溪石并没有显示出来,因为定义时@"自定义UILabel\\n 溪石 "溪石前插入了一个换行符\\n,导致文本被分成了两行,而UILabel默认只显示一行,溪石显示到了第二行,因此看不见!所以需要设置行数:

aLabel.numberOfLines = 0;


这里怎么是零?!我要的是换行,起码大于1吧!这里当然可以设置1、2、3...表示需要的行数,不过,0表示“无限行”,适用于自动换行等无法确切知道总行数的情形。
接着,还是回到attributedText进行设置:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 8.0;//调整行间距
paragraphStyle.alignment = NSTextAlignmentCenter;
[str addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [str length])];

这里用lineSpacing属性设置了行间距,另外又设置了一次对齐属性alignment,因为设置文本格式会覆盖UILabeltextAlignment属性,因此需要重新设置一次。

出发吧!这里只是起点

到这里,UILabel的定制方法基本都已经介绍到了,再来复习一下:

  1. 自定义字体:介绍了如何使用系统之外的TTF字库来设置Font。
  2. 制作不规则的边框:介绍了用CALayer和CAShapeLayer及贝塞尔路径来自定义UILabel的边框,包括形状与颜色。
  3. 显示不同字体和颜色:用attributedText属性代替text属性,这样可以对一段文字分别设定文字的样式。
  4. 调整缩进与行距:在attributedText的基础上,利用NSMutableParagraphStyle设置行高等“段落属性”。

实际上,大家是不是有点儿体会到,UILabel的定制和Word等文本编辑器中的“排版”知识是一致的,在对UI设计越来越重视的软件开发实践中,“富文本”排版是不可或缺的知识,刚开始开发iOS的小伙伴,可以以本文中介绍的知识为基础,进一步了解各个类的属性,做出多种多样的文字效果!
【欢迎关注溪石,获取更多开发技巧】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,323评论 19 139
  • 我还爱你 即使你已经远去 我的身躯放在灿烂的阳光里 可心灵躲在死寂的黑暗里自怜自已 我还爱你 即使你已经不是原来的...
    眸莘阅读 1,729评论 0 1
  • 寻她 春雨菲菲,万物苏,一夜梨花凝泪, 无人应无语答。 前路迢迢,梦境寻,两心相思牵挂, 花落终归谁家。 小桥流水...
    東方木阅读 1,690评论 0 1
  • 悦己者容 《明朝那些事儿》第一部早在三年前就很火了,不过一直没有关注过。直到最近它的第七部也就是终结篇出来后,发现...
    悦己者容Grace阅读 3,255评论 0 4
  • 66七绝:杏花 原创:篱菊傲霜 欲来玄鸟春正旺, 娇杏忙施粉面妆。 无意春风多爱恋, 纷纷落韵噙幽香。
    篱菊傲霜阅读 1,670评论 0 2