美文网首页
App 面向UI编程

App 面向UI编程

作者: 笨驴爱吃胡萝卜 | 来源:发表于2020-02-16 16:36 被阅读0次
image-20190324231208978.png

前言

对于优化的必要行和优化的可行性,App 渲染性能优化是一个普遍存在的问题。页面卡顿,手机耗电等问题渲染的优惠都能解决或者减轻 问题造成的影响。

app 性能 是个相比渲染更大的命题,渲染的优化是性能优化很重要的一部分。

阻塞主线程的任务,主要分为上面这三大类。文本和布局的计算、渲染、解码、绘制都可以通过各种方式异步执行,但 UIKit 和 Core Animation 相关操作必需在主线程进行。

具体方法和途径

其中之一 同步渲染排版

在图文混排的情况下,解决方案 实践得出的一个方案

可能不是最优,但是 代码量和实践复杂度是最小

如一个 Controller 中添加一个view, viewdidload 在整体绘制之前,我们要得到所有图片在CTFrame中位置

编排一个 自己的class 对于绘制的Data 进行进一步封装

CoreTextData *data = [[CoreTextData alloc] init];
data.ctFrame = frame; //CTFrame
data.height = textHeight;

这个是核心,核心的表现是,Frame 和Height 这两个属性 一旦确定,对于上下文的Context 就有自己的归宿。CGContext 为CoreGraphic 库Class ,虽然CoreText 为了文案 的绘制提供了便利,但是,还是要借助CoreGraphic对图片进行绘制,和必要条件的获取。

起步开始-我的Attribute

在这之前,要做的事情:

  1. text 直接变成 attributeString

  2. image 记录下name & 位置 将image 也变成 attributeString(其实是为了占位)

这样 产生的 NSAttributedString 是全部的了

重点的CGFrame

绘制区域是最为困难想明白的部分,CoreText 对于不常用的API 集合 Frame 的获取有很多方式,最常用的方式

  1. 通过
    1. 通过CTFramesetterRef CTFramesetterCreateWithAttributedString 方法 开始使用 attributeString 对象. ->生成 CTFramesetterRef 对象
    2. 利用 CTFramesetterRef 对象 获得要绘制的区域的高度(宽度是自己定)获取 width / height
    3. 一切为了 CTFrameRef 对象的生成服务

​ // 1.有了width / height 配置 对应的CGMutablePathRef path 对象

 CGMutablePathRef path = CGPathCreateMutable();
 CGPathAddRect(path, NULL, CGRectMake(0, 0, config.width, height));
    
CTFrameRef  对象生成 用到上文 费了半天功夫来配置出来的path 

​ ( CTFramesetterRef 对象 根据 attributeString 来的)

CTFrameRef CTFramesetterCreateFrame(
    CTFramesetterRef framesetter,
    CFRange stringRange,
    CGPathRef path,
    CFDictionaryRef _Nullable frameAttributes )

提示: CGPathRef参数 根据Height->也是attributeString ; CTFramesetterRef 对象也是根据 attributeString 获得

最后的Draw InView

Draw 在view 里面 通过自己的编排生成的 CoreTextData 对象,来CTFrameDraw 画到view 上。

在custom view 里面的draw 方法

CustomView.m 
- (void)drawRect:(CGRect)rect{
  
}
  
 CGContextRef context = UIGraphicsGetCurrentContext();//1.获取当前绘图上下文
 CGContextSetTextMatrix(context, CGAffineTransformIdentity);//2
 CGContextTranslateCTM(context, 0, self.bounds.size.height);//2
 CGContextScaleCTM(context, 1.0, -1.0); //2.旋转坐坐标系(默认和UIKit坐标是相反的)

 draw //3 绘制

4.1 draw 普通文本

CTFrameDraw(self.data.ctFrame, context); //文字绘画

这个可以扩展 CTLineDraw / CTRunDraw

4.2 draw 图片
CG_EXTERN void CGContextDrawImage(
CGContextRef cg_nullable c,
CGRect rect,
CGImageRef cg_nullable image)

提示1 上下文 2 图片位置 3 图片(UIImage image = [UIImage imageNamed:imageData.name];

重点在队列的-异步排版

阻塞主线程的任务,主要分为上面这三大类。文本和布局的计算、渲染、解码、绘制都可以通过各种方式异步执行,但 UIKit 和 Core Animation 相关操作必需在主线程进行。

异步排版-目前看到的异步排版 一般是在 Draw 的时候,对于Draw 方式很多,CoreText 提供丰富的Draw 方式

CTLineDraw

RunDraw

FrameDraw 等等 衍生的API

数据

难点

  1. 异步排版的队列控制 -线程安全 就是一个实现方法很多的命题

  2. 如何优雅的获取AttributeString ,对于纯文本还好,但是对于图文,可能获取的时候,图片的占位 要有自己的设计结构 (优雅的布局框架)

  3. 数据监听,工具选择 和 内存监听实时

  4. 网络参考资料匮乏,大部分都是老资料,新款iPhone 和新系统的进一步优化方案FrameWork 资料匮乏

总结

总结: 都是 AttributeString 文字 用CoreText 图片 用 CoreGraphics

资料参考

基础知识

基础知识_2

基础知识_3

开源demo

开源demo2

性能测试demo

实践优化

Graver 美团排版

TextKit wwdc

页面流畅的技术点

Texture

https://my.oschina.net/FEEDFACF/blog/1858441

相关文章

  • App 面向UI编程

    前言 对于优化的必要行和优化的可行性,App 渲染性能优化是一个普遍存在的问题。页面卡顿,手机耗电等问题渲染的优惠...

  • iOS(swift)类和结构体的区别

    类是面向对象编程;结构体是面向协议编程(面向对象的升级)。swift推荐在app中使用结构体(struct),类(...

  • 面向指针编程(一)

    面向对象编程,面向设计模式编程(亦即设计模式),面向接口编程,面向模板编程(亦即泛型编程),面向函数编程(亦即函数...

  • 理论三:面向对象相比面向过程有哪些优势?面向过程真的过时了吗?

    什么是面向过程编程与面向过程编程语言?面向对象编程相比面向过程编程有哪些优势?为什么说面向对象编程语言比面向过程编...

  • 探秘Spring AOP

    编程范式概览 主要有面向对象编程、面向过程编程、函数式编程、事件驱动编程、面向切面编程。面向过程编程是以过程为中心...

  • Swift和OC的区别

    一、编程范式 Swift可以面向协议编程、面向函数编程、面向对象编程。 OC主要是面向对象编程。 二、类型安全 S...

  • ES6中的类的总结

    js常用的编程模式有面向过程编程和面向对象编程(1)面向过程编程“面向过程”(Procedure Oriented...

  • python面向对象1

    编程思想 编程思想:面向过程编程(穷人思想)、函数式编程、面向对象编程(富豪) 面向过程编程: 算法和逻辑 函数式...

  • AOP(一)---什么是AOP

    要理解AOP我们先要理解其他一些概念: 面向过程编程 面向对象编程 面向切面编程 面向过程编程OPP 面向过程的编...

  • Python全栈之路系列之面向对象基础

    面向对象基本介绍 Python编程方式: 面向过程编程 面向函数编程 面向对象编程 名称定义: 如果函数没有在类中...

网友评论

      本文标题:App 面向UI编程

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