iOS 7系列译文:认识 TextKit




- NSTextStorage *textStorage = [NSTextStorage new];
- NSLayoutManager *layoutManager = [NSLayoutManager new];
- [textStorage addLayoutManager: layoutManager];
- NSTextContainer *textContainer = [NSTextContainer new];
- [layoutManager addTextContainer: textContainer];
- UITextView *textView = [[UITextView alloc] initWithFrame:someFrame
- textContainer:textContainer];
- NSTextStorage *sharedTextStorage = originalTextView.textStorage;
- NSLayoutManager *otherLayoutManager = [NSLayoutManager new];
- [sharedTextStorage addLayoutManager: otherLayoutManager];
- NSTextContainer *otherTextContainer = [NSTextContainer new];
- [otherLayoutManager addTextContainer: otherTextContainer];
- UITextView *otherTextView = [[UITextView alloc] initWithFrame:someFrame
- textContainer:otherTextContainer];
- NSTextContainer *thirdTextContainer = [NSTextContainer new];
- [otherLayoutManager addTextContainer: thirdTextContainer];
- UITextView *thirdTextView = [[UITextView alloc] initWithFrame:someFrame
- textContainer:thirdTextContainer];
- otherTextView.scrollEnabled = NO;
- - (NSString *)string;
- - (NSDictionary *)attributesAtIndex:(NSUInteger)location
- effectiveRange:(NSRangePointer)range;
- - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;
- - (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range;
- @implementation TKDHighlightingTextStorage
- {
- NSMutableAttributedString *_imp;
- }
- - (id)init
- {
- self = [super init];
- if (self) {
- _imp = [NSMutableAttributedString new];
- }
- return self;
- }
- - (NSString *)string
- {
- return _imp.string;
- }
- - (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range
- {
- return [_imp attributesAtIndex:location effectiveRange:range];
- }
- - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str
- {
- [_imp replaceCharactersInRange:range withString:str];
- [self edited:NSTextStorageEditedCharacters range:range
- changeInLength:(NSInteger)str.length - (NSInteger)range.length];
- }
- - (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range
- {
- [_imp setAttributes:attrs range:range];
- [self edited:NSTextStorageEditedAttributes range:range changeInLength:0];
- }
- _textStorage = [TKDHighlightingTextStorage new];
- [_textStorage addLayoutManager: self.textView.layoutManager];
- - (void)processEditing
- {
- [super processEditing];
- static NSRegularExpression *iExpression;
- NSString *pattern = @"i[\\p{Alphabetic}&&\\p{Uppercase}][\\p{Alphabetic}]+";
- iExpression = iExpression ?: [NSRegularExpression regularExpressionWithPattern:pattern
- options:0
- error:NULL];
- NSRange paragaphRange = [self.string paragraphRangeForRange: self.editedRange];
- [self removeAttribute:NSForegroundColorAttributeName range:paragaphRange];
- [iExpression enumerateMatchesInString:self.string
- options:0 range:paragaphRange
- usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
- {
- [self addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:result.range];
- }];
- }

- - (CGFloat) layoutManager:(NSLayoutManager *)layoutManager
- lineSpacingAfterGlyphAtIndex:(NSUInteger)glyphIndex
- withProposedLineFragmentRect:(CGRect)rect
- {
- return floorf(glyphIndex / 100);
- }
- static NSDataDetector *linkDetector;
- linkDetector = linkDetector ?: [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:NULL];
- NSRange paragaphRange = [self.string paragraphRangeForRange: NSMakeRange(range.location, str.length)];
- [self removeAttribute:NSLinkAttributeName range:paragaphRange];
- [linkDetector enumerateMatchesInString:self.string
- options:0
- range:paragaphRange
- usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
- {
- [self addAttribute:NSLinkAttributeName value:result.URL range:result.range];
- }];
- - (BOOL)layoutManager:(NSLayoutManager *)layoutManager shouldBreakLineByWordBeforeCharacterAtIndex:(NSUInteger)charIndex
- {
- NSRange range;
- NSURL *linkURL = [layoutManager.textStorage attribute:NSLinkAttributeName
- atIndex:charIndex
- effectiveRange:&range];
- return !(linkURL && charIndex > range.location && charIndex <= NSMaxRange(range));
- }


- - (void)updateExclusionPaths
- {
- CGRect ovalFrame = [self.textView convertRect:self.circleView.bounds
- fromView:self.circleView];
- ovalFrame.origin.x -= self.textView.textContainerInset.left;
- ovalFrame.origin.y -= self.textView.textContainerInset.top;
- UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect:ovalFrame];
- self.textView.textContainer.exclusionPaths = @[ovalPath];
- }
原文链接:Max Seelemann 翻译:伯乐在线 - 和谐老约翰
iOS 7系列译文:认识 TextKit的更多相关文章
- iOS开发系列--Swift语言
概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...
- iOS开发系列文章(持续更新……)
iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...
- iOS开发系列--App扩展开发
概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...
- iOS开发系列--Swift进阶
概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...
- iOS开发系列--通知与消息机制
概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...
- iOS开发系列--数据存取
概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...
- iOS开发系列--网络开发
概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...
- iOS开发系列--C语言之基础知识
概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...
- iOS开发系列--让你的应用“动”起来
--iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...
随机推荐
- python numpy 判断ndarray 中是否有 nan
numpy.isnan(myarray).any() 下面讨论了哪一种方法的速度最快 reference: stackoverflow.com/questions/911871/detect-if-a ...
- hdu2874(lca / tarjan离线 + RMQ在线)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意: 给出 n 个顶点 m 条边的一个森林, 有 k 个形如 x y 的询问, 输出 x, ...
- Zjoi2011 看电影
最近在学习一些概率的东西.. 一个随机试验称为 Laplace 试验,当且仅当它满足如下两个条件: (ⅰ) 试验结果 (样本点) 的个数是有限的.(Ω 是有限集) (ⅱ) 任意两个基本事件的概率均相等 ...
- uoj #185. 【ZJOI2016】小星星
#185. [ZJOI2016]小星星 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有 nn 颗小星星,用 mm 条彩色的细线串了起来,每条细线连着两颗小星星.有一天她发现,她的饰品被破坏 ...
- 洛谷P3043 [USACO12JAN]牛联盟Bovine Alliance
P3043 [USACO12JAN]牛联盟Bovine Alliance 题目描述 Bessie and her bovine pals from nearby farms have finally ...
- 洛谷P1065 作业调度方案
P1065 作业调度方案 题目描述 我们现在要利用m台机器加工n个工件,每个工件都有m道工序,每道工序都在不同的指定的机器上完成.每个工件的每道工序都有指定的加工时间. 每个工件的每个工序称为一个操作 ...
- HDU1272-小希迷宫
题目链接:点击打开链接 Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首 ...
- 洛谷P2846 光开关Light Switching
题目描述 灯是由高科技--外星人鼠标操控的.你只要左击两个灯所连的鼠标, 这两个灯,以及之间的灯都会由暗变亮,或由亮变暗.右击两个灯所连的鼠 标,你就可以知道这两个灯,以及之间的灯有多少灯是亮的.起初 ...
- 使用 dbutils 的结果集包装类 StringTrimmedResultSet
1.功能 StringTrimmedResultSet 的功能是去掉结果集中数据的前后空格,这个方法是在取结果的时候处理. 2.使用 一般在新建 QueryRunner 对象的时候使用: QueryR ...
- (转)yi_meng linux 下 ifcfg-eth0 配置 以及ifconfig、ifup、ifdown区别
linux 下 ifcfg-eth0 配置 以及ifconfig.ifup.ifdown区别 原文:https://www.cnblogs.com/yi-meng/p/3214471.html这3个命 ...