UITextView高级用法

来源:互联网 发布:万合天宜 知乎 编辑:程序博客网 时间:2024/06/04 23:35

原链http://blog.csdn.net/a2657222/article/details/41213903


目前有三个需求,1.给每个字体加边框;2.随着文字的内容的变化改变控件大小;3点击单词能够识别出该单词。
其实要实现这三个功能已经不是上层API能做的事情了,这时候你要理解清楚UITextView的整个实现过程,才有可能找到解决方案。
a.苹果Text Kit Framework

从上面可以看出UITextVIew在框架中的位置,实际上它继承了UIScrollView。

从上面可以看出UITextVIew内部是怎么实现文字显示和排版布局的。具体的实现可以看这篇文章:https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html

b.给每个字体加边框



其实这个效果的实现思路就是给每个字加上一个背景,那么怎么给每个字后面加一个黑色的,比原来稍微大一些的字呢?
我原来的想法是用另外一个UITextView去实现这个功能,后来我分析这个方案是有可能失败的,因为你放大字体,那么就有可能导致排版和原来不一样,那么这个方案就失去了意义,因为编程就必须考虑代码的健壮性。
后来就在网上寻找怎么去画一个字?最后的代码像是这样的:
-(void)drawRect:(CGRect)rect{   NSMutableDictionary *attributes = [[NSMutableDictionaryalloc]init];    [attributessetObject:self.fontforKey:NSFontAttributeName];    [attributessetObject:[NSNumbernumberWithFloat:8]forKey:NSStrokeWidthAttributeName];    [attributessetObject:[UIColorblackColor]forKey:NSStrokeColorAttributeName];   NSMutableParagraphStyle*paragraphStyle = [[NSMutableParagraphStylealloc]init];    paragraphStyle.alignment =self.textAlignment;    [attributessetObject:paragraphStyleforKey:NSParagraphStyleAttributeName];   if(self.text.length != 0) {       CGPoint point = [self.layoutManagerlocationForGlyphAtIndex:0];       if (self.textAlignment==NSTextAlignmentLeft) {            rect.origin.x = point.x;        }        rect.origin.y =9;    }        [self.textdrawInRect:rectwithAttributes:attributes];    [selfsetNeedsDisplay]; }

c.随着文字的内容的变化改变控件大小;

这个在ios8下面实在没有什么好的实现方案,无论是去寻找字体大小和行数还是scrollView.contentSize都不够准确,后来想一下这个页面布局可能是UIView负责做的事情,后来发现UIView有两个方法已经实现了这个功能:
- (CGSize)sizeThatFits:(CGSize)size;    // return 'best' size to fit given size. does not actually resize view. Default is return existing view size - (void)sizeToFit;                       // calls sizeThatFits: with current view bounds and changes bounds size.

d.点击单词能够识别出该单词
很明显这个涉及到每个字符的位置,只要找到了单词的位置和你点击屏幕的位置,就能找到点击的单词。
通过上面的分析,我们发现UITextView对于文字的布局,有一个叫做NSLayoutManager的类,其中有这么一个方法:
CGFloat fraction =0;       NSInteger characterIndex = [textView.layoutManager characterIndexForPoint:locationinTextContainer:textView.textContainerfractionOfDistanceBetweenInsertionPoints:&fraction];
获取你点击位置的字符index,fraction如果是大于0并且小于1,就说明你点击的就是这个字符,没有超出范围,知道了字符的位置,后面判断是否为单词就很简单的。

e.总结

通过对UITextView的操作发现当你的需求增多的时候,你必须了解整个框架,而不是仅仅调用几个系统的API,你需要知道你的需求在系统的哪个层次上面。



“双语播放器”已在app store上架,欢迎大家前去下载(主要用于看电影,学英语,程序员一定要学好英语!)

这里是链接:

https://itunes.apple.com/cn/app/shuang-yu-bo-fang-qi-kan-dian/id950279764?mt=8


0 0