欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由落影发表于云+社区专栏

前言

app在渲染视图时,需要在坐标系中指定绘制区域。 这个概念看似乎简单,事实并非如此。

When an app draws something in iOS, it has to locate the drawn content in a two-dimensional space defined by a coordinate system. This notion might seem straightforward at first glance, but it isn’t.

正文

我们先从一段最简单的代码入手,在drawRect中显示一个普通的UILabel; 为了方便判断,我把整个view的背景设置成黑色:

- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
NSLog(@"CGContext default CTM matrix %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 28)];
testLabel.text = @"测试文本";
testLabel.font = [UIFont systemFontOfSize:14];
testLabel.textColor = [UIColor whiteColor];
[testLabel.layer renderInContext:context];
}

这段代码首先创建一个UILabel,然后设置文本,显示到屏幕上,没有修改坐标。 所以按照UILabel.layer默认的坐标(0, 0),在左上角进行了绘制。

UILabel绘制

接着,我们尝试使用CoreText来渲染一段文本。

- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
NSLog(@"CGContext default matrix %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:@"测试文本" attributes:@{
NSForegroundColorAttributeName:[UIColor whiteColor],
NSFontAttributeName:[UIFont systemFontOfSize:14],
}];
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) attrStr); // 根据富文本创建排版类CTFramesetterRef
UIBezierPath * bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 20)];
CTFrameRef frameRef = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), bezierPath.CGPath, NULL); // 创建排版数据
CTFrameDraw(frameRef, context);
}

首先用NSString创建一个富文本,然后根据富文本创建CTFramesetterRef,结合CGRect生成的UIBezierPath,我们得到CTFrameRef,最终渲染到屏幕上。 但是结果与上文不一致:文字是上下颠倒。

CoreText的文本绘制

从这个不同的现象开始,我们来理解iOS的坐标系。

坐标系概念

在iOS中绘制图形必须在一个二维的坐标系中进行,但在iOS系统中存在多个坐标系,常需要处理一些坐标系的转换。 先介绍一个图形上下文(graphics context)的概念,比如说我们常用的CGContext就是Quartz 2D的上下文。图形上下文包含绘制所需的信息,比如颜色、线宽、字体等。用我们在Windows常用的画图来参考,当我们使用画笔

iOS开发必会的坐标系探究的更多相关文章

  1. [转]iOS开发中的火星坐标系及各种坐标系转换算法

     iOS开发中的火星坐标系及各种坐标系转换算法 源:https://my.oschina.net/u/2607703/blog/619183   其原理是这样的:保密局开发了一个系统,能将实际的坐标转 ...

  2. iOS开发中的火星坐标系及各种坐标系转换算法

    原文地址:http://m.oschina.net/blog/619183?ref=myread 其原理是这样的:保密局开发了一个系统,能将实际的坐标转换成虚拟的坐标.所有在中国销售的数字地图必须使用 ...

  3. 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取”产品付费数量等于0的问题”】

    转的别人的 看到很多童鞋问到,为什么每次都返回数量等于0?? 其实有童鞋已经找到原因了,原因是你在 ItunesConnect 里的 “Contracts, Tax, and Banking”没有完成 ...

  4. iOS开发-获取子视图坐标系中Point、Rect在父视图坐标系中的实际值

    iOS提供了方法来完成上述值得转换 convertRect:toView:, convertRect:FromView: convertPoint:toView: and convertPoint:f ...

  5. iOS开发必看的博客汇总

    OneV's Den http://onevcat.com/ 沉船家园 http://beyondvincent.com/ NSHipster http://nshipster.cn/ Limboy ...

  6. 新手必看,史上最全的iOS开发教程集锦,没有之一!

    最近大火的iPhone XS Max和iPhone XS,不知道有没有同学已经下手了呢?一万三的价位确实让很多人望而却步啊.据说为了赢得中国的用户,专门出了双卡双待的,可想而知中国市场这块“肥肉”人人 ...

  7. 学习ios(必看经典)牛人40天精通iOS开发的学习方法

    学习ios(必看经典)牛人40天精通iOS开发的学习方法 描述 这是一套从一个对iOS开发感兴趣的学员到iOS开发高手的系统.专业的课程体系.以培养企业开发真正需要的人才为目标,每个知识点都用案例来讲 ...

  8. iOS开发 iOS10推送必看

    iOS10更新之后,推送也是做了一些小小的修改,下面我就给大家仔细说说.希望看完我的这篇文章,对大家有所帮助. 一.简单入门篇---看完就可以简单适配完了 相对简单的推送证书以及环境的问题,我就不在这 ...

  9. 【热门收藏】iOS开发人员必看的精品资料(100个)——下载目录

    iPhone.iPad产品风靡全球,巨大的用户群刺激着iOS软件开发需求,然而国内人才缺口很大,正处于供不应求的状态,ios开发前景大好.我们整理了51CTO下载中心100份热门的ios开发资料,做了 ...

随机推荐

  1. POJ 3107.Godfather 树形dp

    Godfather Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7536   Accepted: 2659 Descrip ...

  2. PYthon第十二天

    1. 生成器 生成器的本质是迭代器, 最简单的生成器函数如下: def foo(x): 1-4行定义了一个简单的生成器函数 yield x+1 yield 和 return 不同, return 结束 ...

  3. SVN忘记登陆用户

    C:\Users\Yaolz\AppData\Roaming\Subversion\auth 删除里面所有文件

  4. 【转】最近用Timer踩了一个坑,分享一下避免别人继续踩

    [转]最近用Timer踩了一个坑,分享一下避免别人继续踩 最近做一个小项目,项目中有一个定时服务,需要向对方定时发送数据,时间间隔是1.5s,然后就想到了用C#的Timer类,我们知道Timer 确实 ...

  5. Django的学习进阶(二)———— name

    一.问题: 在做完第一个demo的时候,由于只是基础学习,所以对于name的使用并不需要很熟练,也不用理解的很深.但是在做音乐网站的时候遇到了关于如何使用name的内容. 由于一个app中会使用到另一 ...

  6. P1613 跑路(倍增 + floyd)

    https://www.luogu.org/problemnew/show/P1613 思路: 1.读入 2.建图 3.对于每一个点,向距离它 2^k 长度的点连一条长度为 1 的边 4.在新图上跑1 ...

  7. javascript 错误监控

    一.错误分类 1,即使运行错误:代码错误, 2.资源加载错误 二. 错误的捕获方式 1.即使运行错误的捕获方式 a. try catch       b.window.onerror 2.资源加载错误 ...

  8. C++探究foreach算法

    for_each在algorithm.h 中 template<class _InIt, class _Fn1> inline _Fn1 for_each(_InIt _First, _I ...

  9. app已损坏,打不开。你应该将它移到废纸篓

    首先声明: 有可能并非你安装的软件已损坏,而是Mac系统的安全设置问题,因为这些应用都是破解或者汉化的,那么解决方法就是临时改变Mac系统安全设置. 出现这个问题的解决方法: 修改系统配置:系统偏好设 ...

  10. shell解析my.cnf配置文件

    my.cnf配置格式如下 vi my.cnf[client]port=3306socket=/tmp/mysql.socket [mysqld]port=3306server-id=1datadir= ...