余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

Swift中的CGRect、CGSize和CGPoint(外贸中swift)

xiyangw 2022-12-03 13:28 20 浏览 0 评论

在我转向Swift后,我逐渐避免写出具有OC风格的swift代码并开始真正利用上这门语言的优点。

Swift中的CGRect、CGSize和CGPoint(外贸中swift)

但最近我发现在处理CGGeometry结构体时,我依然使用了丑陋的,非Swift风格的代码。CGGeometry结构体指的是:

CGRect, CGSize, CGPoint

C风格语法,披着狼皮的羊

我有一种强烈的感觉,许多Swift程序员都会对此感到内疚,请写过下面这种代码的同学举手:

letrect=CGRectMake(0,0,100,100)
letpoint=CGPointMake(0,0)
letsize=CGSizeMake(100,100)

别担心,这并不是什么应该羞愧的事情。

这么写的问题在于它不符合Swift的语法风格,虽然可以正常运行,但是它看上去更像是一段OC,甚至是Java代码。

一个有经验的iOS开发者一眼就能看出这几行代码的含义,他们不需要CGGeometry结构体的初始化函数中的参数名。但Swift希望对所有新手很友好,如果他们第一眼看到这些代码一定会不知所措,因为他们无法理解这些数字的含义。因此,我们应该使用Swift版本的代码:

letrect=CGRect(x:0,y:0,width:100,height:100)
letsize=CGSize(width:100,height:100)
letpoint=CGPoint(x:0,y:0)

尽管代码变得略微冗长一些,但是它现在具备良好的可读性。而且另一个额外的好处在于,参数不必局限于CGFloat类型了,我们还可以使用Int和Double类型的参数。查看一下CGRect结构体的定义和CGRectMake函数的定义就很容理解了:

extensionCGRect{
publicinit(x:CGFloat,y:CGFloat,width:CGFloat,height:CGFloat)
publicinit(x:Double,y:Double,width:Double,height:Double)
publicinit(x:Int,y:Int,width:Int,height:Int)
}

publicfuncCGRectMake(x:CGFloat,
_y:CGFloat,
_width:CGFloat,
_height:CGFloat)->CGRect

Zero

你或许还在使用这样的代码:

letrect=CGRectZero
letsize=CGSizeZero
letpoint=CGPointZero

是时候更新一下自己的知识体系,改用swift风格的语法了。别担心,新的语法只需要增加一个字符:

letrect=CGRect.zero
letsize=CGSize.zero
letpoint=CGPoint.zero

这样写的好处在于Xcode的代码高亮机制会将.zero高亮显示,这样它会更醒目,降低你的认知负荷。

获取值

如果你曾经或任然是一名优秀的OC开发者,你应该写过这样的代码来获取结构体中的值:

CGRectframe=CGRectMake(0,0,100,100)
CGFloatwidth=CGRectGetWidth(frame)
CGFloatheight=CGRectGetHeight(frame)
CGFloatmaxX=CGRectGetMaxX(frame)
CGFloatmaxY=CGRectGetMaxY(frame)

不过不妨先思考一下,为什么不能直接获取值呢?比如这样:

CGFloatwidth=frame.size.width
CGFloatheight=frame.size.height

For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.— Apple, CGGeometry Reference Documentation

(译者注:)考虑两个CGRect,第一个origin是[0,0],size是[10, 10]。第二个的origin是[10,10],size是[-10, -10]。两者其实是等价的,无论是OC还是Swift都支持这两种写法。问题在于,在OC中,获取结构体的属性就直接获取到它的真实值了,这个值有可能为负。所以OC建议我们调用系统API而不是直接获取值,而在Swift中,width、height等被设计为计算属性,自然就不存在这样的问题了。

由于系统提供了完备的API,很多人觉得不直接获取值也不是什么问题。不过Swift提供了简单的点语法表达式,将我们从这种不美观的API中解放出来:

letframe=CGRect(x:0,y:0,width:100,height:100)
letwidth=frame.width
letheight=frame.height
letmaxX=frame.maxX
letmaxY=frame.maxY

可变性

letframe=CGRect(x:0,y:0,width:100,height:100)
letview=UIView(frame:frame)
view.frame.origin.x+=10

现在,你不仅可以直接修改结构体中的某个值,还可以直接替换整个子结构体:

letview=UIView(frame:.zero)
view.frame.size=CGSize(width:10,height:10)
view.frame.origin=CGPoint(x:10,y:10)

单单这个特性就足够我们放弃OC,投入Swift的怀抱了。我们不必非得重新创建一个结构体实例再修改了,不到两年前,我们OC开发者还被迫写下这样的代码:

CGRectframe=CGRectMake(0,0,100,100);
UIView*view=[[UIViewalloc]initWithFrame:frame];
CGRectnewFrame=view.frame;
newFrame.size.width=view.frame.origin.x+10;
view.frame=newFrame;

我不知道你怎么想,但是写出这样的代码快要把我逼疯了。根据view的frame重新创建结构体,修改它,然后再把view的frame改成这个结构体,再见了,再也不见!

最后说一句,以上这些改变还适用于UIKit中的其他结构体:

//UIEdgeInsets
varedgeInsets=UIEdgeInsets(top:10,left:10,bottom:10,right:10)
edgeInsets.top+=10

//UIOffset
varoffset=UIOffset(horizontal:10,vertical:10)
offset.vertical+=10

示范代码可以在作者的github上找到

相关推荐

前后端分离 Vue + NodeJS(Koa) + MongoDB实践

作者:前端藏经阁转发链接:https://www.yuque.com/xwifrr/gr8qaw/vr51p4写在前面闲来无事,试了一下Koa,第一次搞感觉还不错,这个项目比较基础但还是比较完整了,...

MongoDB 集群如何工作?

一、什么是“MongoDB”?“MongoDB”是一个开源文档数据库,也是领先的“NoSQL”数据库,分别用“C++”“编程语言”编写,使用带有“Schema”的各种类似JSON的文档,是也分别被认为...

三部搭建mongo,和mongo UI界面

三步搭建mongo,和mongoUI界面安装首先你需要先有一个docker的环境检查你的到docker版本docker--versionDockerversion18.03.1-ce,b...

Mongodb 高可用落地方案

此落地方案,用于实现高可用。复制集这里部署相关的复制集,用于实现MongoDB的高可用。介绍MongoDB复制集用于提供相关的数据副本,当发生硬件或者服务中断的时候,将会从副本中恢复数据,并进行自动...

一次线上事故,我顿悟了MongoDB的精髓

大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?让我们一起,一探究竟,继续学习MongoDB分片的理论与实践,...

IDEA中安装MongoDB插件-再也无要nosql manager for mongodb

大家都知道MongoDB数据库作为典型的非关系型数据库被广泛使用,但基于MongoDB的可视化管理工具-nosqlmanagerformongodb也被用的较多,但此软件收费,所以国内的破解一般...

数据库监控软件Lepus安装部署详解

Lepus安装部署一、软件介绍Lepus是一套开源的数据库监控平台,目前已经支持MySQL、Oracle、SQLServer、MongoDB、Redis等数据库的基本监控和告警(MySQL已经支持复...

YAPI:从0搭建API文档管理工具

背景最近在找一款API文档管理工具,之前有用过Swagger、APIManager、Confluence,现在用的还是Confluence。我个人一直不喜欢用Swagger,感觉“代码即文档”,让代...

Mac安装使用MongoDB

下载MongoDB包:https://www.mongodb.com/download-center解压mongodb包手动解压到/usr/local/mongodb文件夹配置Mac环境变量打开环境...

保证数据安全,不可不知道的MongoDB备份与恢复

大家在项目中如果使用MongoDB作为NOsql数据库进行存储,那一定涉及到数据的备份与恢复,下面给大家介绍下:MongoDB数据备份方法在MongoDB中我们使用mongodump命令来备...

MongoDB数据备份、还原脚本和定时任务脚本

备注:mongodump和mongorestore命令需要在MongoDB的安装目录bin下备份脚本备份格式/usr/local/mongodb/bin/mongodump -h ...

等保2.0测评:mongoDB数据库

一、MongoDB介绍MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产...

MongoDB入门实操《一》

什么是MongoDBMongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之...

Python安装PyMongo的方法详细介绍

欢迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练、PDF电子文档、面试集锦、学习资料等。前言本文主要给大家介绍的是关于安装PyMongo的...

第四篇:linux系统中mongodb的配置

建议使用普通用户进行以下操作。1、切换到普通用户odysee。2、准备mongodb安装包,自行去官网下载。3、解压安装包并重命名为mongodb4.04、配置mongodbcdmongod...

取消回复欢迎 发表评论: