文章来源:淘论文网   发布者: 毕业设计   浏览量: 91



还可以点击去查询以下关键词:
[有关]    [UILabel]    [定制]    [高设置]    [设置]    [探索]    [有关UILabel的行定制高设置的探索]   

项目介绍:

有关UILabel的行高设置的探索

主题 《iOS开发》 by evan

导语

现在的UI,为了展现自己的独特的设计风格,总会“想方设法”的的“为难”开发。其中一项最基本的就是设计UILabel的行高。很多开发都会说,要设置行高,论文,简单啊,设置attributedText就可以,如果深入去探索,会发现,并没有想象的那么简单。

需求

如果有这么一个UI需求

要做的第一步肯定的去设置行高,那么下面我们就来设置一下行高。

1. 创建NSMutableAttributedString设置行高

直接上代码

NSRange range = NSMakeRange(0, [text length]); NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setLineSpacing:12.0];//调整行间距 [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range]; [attributedString addAttribute:NSFontAttributeName value:label.font range:range]; label.attributedText = attributedString;

这里按照UI效果图,设置LineSpacing为12,从16号字到20号字,中英文显示效果如下:

问题:虽然我们按照了效果图设置了行高为12,但是为啥实际效果,行高明显大于12呢?2. 解决行高大于12的问题

出现这个问题,有可能有两个因素,要么是UI标注出错了,要么是代码设置出错了。经过验证,我发现UI标注并没有问题,代码也没问题。

问题出在UILabel上,回忆一下,在我们没有设置行高的年代,UIlabel会有一个默认的行高,经过测量,没设置行高的时候,默认行高大概在3px ~ 4px 之间,那么我就直接设置LineSpacing为8。

效果如下:

2. 现在有一个新的需求,最多显示两行

听到这个需求,觉得简单啊,那就来吧,设置numberOfLines为2不OK了。

事实如此吗?

问题:很奇怪,跟想象的完全不一样,是吧?文字显示的是2行,但是占用了整个UIlabel需要的高度

代码里是这样计算Label高度的:

NSDictionary *dic = @{NSFontAttributeName:label.font, NSParagraphStyleAttributeName:paragraphStyle}; NSStringDrawingOptions options = NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading; CGFloat height = [text boundingRectWithSize:CGSizeMake(_scrollView.bounds.size.width - 60, CGFLOAT_MAX) options:options attributes:dic context:nil].size.height;

首先在UILabel.h里可以看到:

// the underlying attributed string drawn by the label, if set, the label ignores the properties above. @property(nullable, nonatomic,copy) NSAttributedString *attributedText NS_AVAILABLE_IOS(6_0); // default is nil

一旦设置了attributedText,以下这一堆属性将无效:

@property(nullable, nonatomic,copy) NSString *text; // default is nil @property(null_resettable, nonatomic,strong) UIFont *font; // default is nil (system font 17 plain) @property(null_resettable, nonatomic,strong) UIColor *textColor; // default is nil (text draws black) @property(nullable, nonatomic,strong) UIColor *shadowColor; // default is nil (no shadow) @property(nonatomic) CGSize shadowOffset; // default is CGSizeMake(0, -1) -- a top shadow @property(nonatomic) NSTextAlignment textAlignment; // default is NSTextAlignmentLeft @property(nonatomic) NSLineBreakMode lineBreakMode; // default is NSLineBreakByTruncatingTail. used for single and multiple lines of text

我们可以看到lineBreakMode也在里面,那我们就在NSMutableParagraphStyle里设置lineBreakMode :

[paragraphStyle setLineBreakMode:label.lineBreakMode];

运行后,Label的高度还是没什么改变,开题报告,依旧是只显示2行,但是占用了所有高度。

问题应该是在boundingRectWithSize这个方法里,因为这里没有提供任何参数让我们设置UILabel的显示行数,所以,它计算的高度是整个Text需要显示的高度。

OK,既然如此我就换一个计算行高的方式:

CGSize size = [label sizeThatFits:CGSizeMake(_scrollView.bounds.size.width - 60, CGFLOAT_MAX)]; CGFloat height = size.height;

效果如下:

问题: 中文在显示一行的时候,文字底边距离UIlabel的下边,仍然有一个高度,这是怎么回事?3. 探索单行中文底边距的问题#p#分页标题#e#

进入NSMutableParagraphStyle.h,看看有那么可以设置的属性:

@property(NS_NONATOMIC_IOSONLY) CGFloat lineSpacing; @property(NS_NONATOMIC_IOSONLY) CGFloat paragraphSpacing; @property(NS_NONATOMIC_IOSONLY) NSTextAlignment alignment; @property(NS_NONATOMIC_IOSONLY) CGFloat firstLineHeadIndent; @property(NS_NONATOMIC_IOSONLY) CGFloat headIndent; @property(NS_NONATOMIC_IOSONLY) CGFloat tailIndent; @property(NS_NONATOMIC_IOSONLY) NSLineBreakMode lineBreakMode; @property(NS_NONATOMIC_IOSONLY) CGFloat minimumLineHeight; @property(NS_NONATOMIC_IOSONLY) CGFloat maximumLineHeight; @property(NS_NONATOMIC_IOSONLY) NSWritingDirection baseWritingDirection; @property(NS_NONATOMIC_IOSONLY) CGFloat lineHeightMultiple; @property(NS_NONATOMIC_IOSONLY) CGFloat paragraphSpacingBefore; @property(NS_NONATOMIC_IOSONLY) float hyphenationFactor; @property(null_resettable, copy, NS_NONATOMIC_IOSONLY) NSArray<NSTextTab *> *tabStops NS_AVAILABLE(10_0, 7_0); @property(NS_NONATOMIC_IOSONLY) CGFloat defaultTabInterval NS_AVAILABLE(10_0, 7_0); @property(NS_NONATOMIC_IOSONLY) BOOL allowsDefaultTighteningForTruncation NS_AVAILABLE(10_11, 9_0);

可设置的属性并不是很多,不过可一看到一个minimumLineHeight 和 maximumLineHeight 。至此有了一个思考。最小行高应该是font所需要的行高,最高行高应该是font所需行高 + lineSpacing。

于是做如下设置:

[paragraphStyle setMinimumLineHeight:label.font.lineHeight]; [paragraphStyle setMaximumLineHeight:label.font.lineHeight + 8.0];

运行效果如下:

问题:多行 跟 单行的效果不统一,多行的时候底边没有边距,单行的时候底边有边距。这也不是我们所需要的效果,怎么办?

......
......
......

在我研究了多天之后,依然对此无解

不过有两个方案可以解决这个问题:

1.判断UILabel的行数,从而来改变UIlabel下面控件与它的间距:

BOOL isMultiLine = size.height > (label.font.lineHeight + MAX(label.font.lineHeight, 8)) ? YES : NO; // 判断UIlabel的行数 if (isMultiLine) { ... // 设置UIImageView.top = 10; } else { ... // 设置UIImageView.top = 10 - 8; }

2.采用CoreText去自定义Label,里面你可以畅所欲为,控制你想控制的一切。

如果有iOS技术达人,有这方面的经验,希望可以跟您交流,共同进步!!!


这里还有:


还可以点击去查询:
[有关]    [UILabel]    [定制]    [高设置]    [设置]    [探索]    [有关UILabel的行定制高设置的探索]   

请扫码加微信 微信号:sj52abcd


下载地址: http://www.taolw.com/down/8694.docx
  • 上一篇:在OC中使用LevelDB
  • 下一篇:DynamicHeightForCollectionView