美文网首页
boundingRectWithSize以及TextKit文字环

boundingRectWithSize以及TextKit文字环

作者: 金风细细 | 来源:发表于2016-10-27 18:00 被阅读136次

    通过2个例子,复习下textview的相关知识

    一.文字计算大小

    NSString的这个函数:

    - (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingContext *)context NS_AVAILABLE(10_11, 7_0);
    

    用法:

    -(void) countBounding{
        NSString * txt = @"大多来问我的朋友们其实都不是很清楚自己的定位,要么是简单的告诉我高考英语考了多少(亲爱的江苏卷的135和全国二卷的135并不是一个层次的好么……),要么简单说一句觉得自己英语很差。只有两个月你给我一句我英语基础不好,怎么才能过四六级,我真的不是神回答不出来的。所以,第一步,也是最最重要的一步,买一本四六级真题(个人买过星火英语的那个黑皮系列卷,不管什么国内的英语考试都可以来一套,很不错,安利一下)。";
        
        
        CGSize size = CGSizeMake(100, 1000);
        // CGSize size = CGSizeMake(1000, 100);
        CGRect rect =  [txt boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil];
        NSLog(@"rect:s%f, %f",rect.size.width, rect.size.height);
        
        self.textView.text = txt;
        self.textView.frame = CGRectMake( 0, 0, ceil(rect.size.width), ceil(rect.size.height));
    }
    
    

    重要参数:

    size:
    通常,计算出来的区域是以传入的size的宽度为准则的.在宽度填满的基础上,再计算高度.(文档说的)
    所以把我们需要的宽度传入,然后高度写的尽量大,写小了也没关系.

    options:

    • NSStringDrawingUsesLineFragmentOrigin 这个必写,文档说的

    • NSStringDrawingUsesFontLeading 计算行高时使用行距。(字体大小+行间距=行距)

    • NSStringDrawingUsesDeviceMetrics 计算时用象形文字的边框而不是印刷字体的边框

    • NSStringDrawingTruncatesLastVisibleLine 如果传入的size装不下所有文本,文本会被省略号结尾.前提是NSStringDrawingUsesLineFragmentOrigin必写,外加String的line break mode必须是NSLineBreakByWordWrapping或者NSLineBreakByCharWrapping

    • attributes 需要的NSAttributeString的特性

    附上一张重要的图,说明NSAttributeString的某些属性,来源于官网:

    1-1

    二. 文字环绕图片

    1. 吃点入门概念

    如此好的官网不得不看!

    TextKit目前和WebKit平级,上面是三个我们熟悉的文本显示控件


    2-1
    • NSTextContrainer : 规定了文字要画的矩形(可以是任意形状,NSBezierPath) ,它是UITextView等的属性
    • NSTextStorage : 它是NSMutableAttributedString的子类,它规定了要写的text,以及它们的显示属性
    • NSLayoutManager : 负责把Unicode文字变成象形文字.


      2-2

    光看概念和框架只会得到一头雾水.上代码:

    -(void ) testAttribute{
        
        NSString * str = @"三个月说一门流利外语没问题,只要你每天不断练习听力、不断模仿着说,尽量学一些贴近生活的句子,毕竟学语言的目的不仅仅是为了考试,更多运用到生活之中。语言学习需要一小时、一小时的积累,不是大家想象中那样几天就可以掌握一门外语。这一点我很赞同,当初自己在学德语时,也是花了一段时间才能够顺利开口说句子。毕竟,你得花时间去学音标、音素,还得花时间去背单词,才会有接下来的开口说.";
        
        
        NSString * str1 = @"培养自制力是一个漫长艰苦的过程。太多的诱惑随时可能让你功亏一篑。所谓的坚持,是心中纠结疑惑,还是继续在往前走,是自己战胜自己的过程。究竟怎样才能排除诸多干扰呢?其实关键就是要学会心理暗示,提前设想那些诱惑带来的种种负面影响,然后在心中一遍又一遍重复告诉自己。";
        
        NSTextStorage * textStorage = [[NSTextStorage alloc] initWithString:str];
        
        
        CGRect rect = CGRectInset(self.view.bounds, 10, 20);
        
        
        //这一段代码很好的诠释了三者的纠结关系,自己体会-----------
        NSLayoutManager * layoutManager = [[NSLayoutManager alloc] init];
        [textStorage addLayoutManager:layoutManager];
        NSTextContainer * textContainer = [[NSTextContainer alloc] initWithSize:rect.size];
        [layoutManager addTextContainer:textContainer];
        UITextView * textView = [[UITextView alloc] initWithFrame:rect textContainer:textContainer];
        //-----------
        
        [self.view addSubview:textView];
        
        //官网说这个必须写
        [textStorage beginEditing];
    
        //1. 通过AttributedString  设置attribute的属性 -- 这里最好写在textStorage初始化的时候,不然就赋值2次string了.是吧.而且实践得知,这样做显示出来非常慢,估计是因为替换了显示的文字的缘故
        
        //这句话给文字赋上了一种风格
        NSDictionary *attrsDic = @{NSTextEffectAttributeName: NSTextEffectLetterpressStyle};
        NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:str1 attributes:attrsDic];
        [textStorage setAttributedString:attributeStr];
    
        
        //2. 通过对textStorage的addAttribute:value:range来后期设置属性
        // 这个让前三个字变红
        [textStorage addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 3)];
    
        
        [textStorage endEditing];
    }
    
    

    2. 文字环绕

    文字环绕其实就是运用了UITextStorage可以设置任意形状这一特性.它有个exclusionPaths属性,是排除文字的区域.官网这图很形象的告诉我们exclusionPaths存在时,文字的具体表现:

    2-1

    需要注意的是传入的rect必须是相对于textview的rect,而不是图片的frame.
    用UIView的函数转换:

    - (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
    

    直接上代码:

    -(void ) testSurround{
        
        NSString * str = @"三个月说一门流利外语没问题,只要你每天不断练习听力、不断模仿着说,尽量学一些贴近生活的句子,毕竟学语言的目的不仅仅是为了考试,更多运用到生活之中。语言学习需要一小时、一小时的积累,不是大家想象中那样几天就可以掌握一门外语。这一点我很赞同,当初自己在学德语时,也是花了一段时间才能够顺利开口说句子。毕竟,你得花时间去学音标、音素,还得花时间去背单词,才会有接下来的开口说.清朝诗人王永彬曾说:身无饥寒,父母不曾亏我;人无长进,我以何对父母。努力,很多时候不是为了和别人竞争,只是因为我努力就会有收获,没有那么惊天动地,却可以给我带来更丰厚的一笔报酬,给老爸老妈买一件喜欢的衣服,世界那么大,我想带他们去看看。或许努力了依旧过不好自己的一生,改变不了这个社会,但至少,因为努力,我可以成为他们的依靠。或许这就是我们所有普通人努力的意义,为了更有尊严的活着,为了拥有更多选择的机会,为了遇见更好的自己,为了给爱我们的人一点回馈。";
        
        
        UIView* innerView = [[UIView alloc] initWithFrame:CGRectMake(100,100,100, 100)];
        
        [self.view addSubview:innerView];
        
        
        NSTextStorage * textStorage = [[NSTextStorage alloc] initWithString:str];
        
        
        CGRect rect = CGRectInset(self.view.bounds, 10, 20);
        
        
        //这一段代码很好的诠释了三者的纠结关系,自己体会-----------
        NSLayoutManager * layoutManager = [[NSLayoutManager alloc] init];
        [textStorage addLayoutManager:layoutManager];
        NSTextContainer * textContainer = [[NSTextContainer alloc] initWithSize:rect.size];
        [layoutManager addTextContainer:textContainer];
    
        //-----------
        
    
        UITextView* textView = [[UITextView alloc] initWithFrame:self.view.bounds textContainer:textContainer];
        
        [self.view insertSubview:textView belowSubview:innerView];
        
        //官网说这个必须写
        [textStorage beginEditing];
        
        //....
        
        [textStorage endEditing];
        
        CGRect relativeRect = [textView convertRect:innerView.frame fromView:self.view];
        UIBezierPath * path =  [UIBezierPath bezierPathWithRect:relativeRect];
        textView.textContainer.exclusionPaths = @[path];
        innerView.backgroundColor = [UIColor redColor];
    }
    
    

    效果:

    2-2

    Demo

    相关文章

      网友评论

          本文标题:boundingRectWithSize以及TextKit文字环

          本文链接:https://www.haomeiwen.com/subject/cwzduttx.html