textkit html ios,iOS Text Part1:TextKit

0.TextKit包含类讲解

612ba2578de7?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

TextKit_1.png

612ba2578de7?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

TextKit_2.png

如图TextKit_1可以看到,我们一般能接触到的文字控件全是由TextKit封装而成的。

TextKit内的三个类功能如下:

NSTextStorage:保存文字控件要显示的NSAttributedString

NSLayoutManager:掌控文字控件对文字的具体绘制操作

NSTextContainer:把控文字控件的显示的区域

隶属关系如下:

self.textStorage = [[NSTextStorage alloc] init];

self.textLayoutManager = [[NSLayoutManager alloc] init];

self.textContainer = [[NSTextContainer alloc]init];

[self.textStorage addLayoutManager:self.textLayoutManager];

[self.textLayoutManager addTextContainer:self.textContainer];

self.textLayoutManager.delegate = self;

1.开发时的应用

1.1 同一段文字分View显示

612ba2578de7?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Simulator Screen Shot 2016年7月20日 下午7.54.28.png

主角:NSTextStorage####

如图TextKit_2可以看到,NSTextStorage、NSLayoutManager 和 NSTextContainer 之间的箭头都是有两个头的。我试图描述它们的关系是 1 对 N 的关系。就是那样:一个 Text Storage 可以拥有多个 Layout Manager,一个 Layout Manager 也可以拥有多个 Text Container。这些多重性带来了很好的特性。

很有用的一个例子,基于页面的布局:

页面上有多个 Text View ,每个Text View 的 Text Container 都引用同一个 Layout Manager,一个 Text Storage持有这个 Layout Manager,这时这个 Text Storage 就可以将文本分布到多个视图上来显示。

1.2 文字内不规则的区域留白

612ba2578de7?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Simulator Screen Shot 2016年7月20日 下午7.54.05.png

主角:NSTextContainer####

CGRect ovalFrame = [_textView convertRect:_panView.bounds fromView:_panView];

// Simply set the exclusion path

UIBezierPath * ovalPath = [UIBezierPath bezierPathWithOvalInRect:ovalFrame];

_textView.textContainer.exclusionPaths = @[ovalPath];

[_textView setNeedsDisplay];

拿到混入图片的矩形坐标,由矩形坐标获取画圆的贝赛尔曲线,将这个贝赛尔曲线赋值给textContainer.exclusionPaths,很简单的就在正常的显示区域内剪出个"洞"。

1.3 Label实现链接点击的效果

612ba2578de7?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Simulator Screen Shot 2016年7月20日 下午8.31.28.png

主角:NSLayoutManager####

612ba2578de7?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

before.png

612ba2578de7?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

select ing.png

上述为点击高亮前后的显示

两副场景如果是"单独"显示,用attributedString+UILabel应该谁都会,难点就在两副场景的瞬间切换,切换不同的attributedString

step1.预先标定高亮区域

step2.点击时识别是否在高亮区域

step3.在高亮区域,切换Label的attributedString

1.3.1 预先标定高亮区域

UI层面预先标定:

特殊区域文字颜色与普通文字颜色不同,通过[attributedString addAttribute:NSForegroundColorAttributeName value:range:]的方式来实现

数据层面预先标定:

@property (nonatomic, copy) NSMutableArray * selectableRanges;

label设置selectableRanges属性用于保存所有特殊区域的range

1.3.2 点击时识别是否在高亮区域

NSUInteger touchedChar = [self.textLayoutManager glyphIndexForPoint:location inTextContainer:self.textContainer];

获取"点击点"所点中字符的index,然后遍历selectableRanges内的每一个range,看是否有哪个range包含了这个index

没有一个range包含那就罢了

有一个range包含就进行下一步

1.3.3 在高亮区域,切换Label的attributedString

-(void)updateShowTextWithRange:(NSRange)range color:(UIColor *)color

{

NSMutableAttributedString * muAttr = [self.attributedText mutableCopy];

if (range.length <= 0) {

[muAttr removeAttribute:NSBackgroundColorAttributeName range:self.selectRange];

}else{

[muAttr addAttribute:NSBackgroundColorAttributeName value:color range:range];

}

self.attributedText = [muAttr copy];

self.selectRange = range;

}

通过[attributedString addAttribute: NSBackgroundColorAttributeName value:range:]的方式更新点中range背景色,然后重新绘制

- (void)drawTextInRect:(CGRect)rect

{

CGPoint textOffset;

NSRange glyphRange = [self.textLayoutManager glyphRangeForTextContainer:self.textContainer];

textOffset = [self calcTextOffsetForGlyphRange:glyphRange];

//绘制背景

[self.textLayoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textOffset];

//绘制字符

[self.textLayoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textOffset];

}

学习来源:

http://objccn.io/issue-5-1/

https://github.com/m1entus/MZSelectableLabel

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值