前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >StoryBoard——高级进阶之“热重载”

StoryBoard——高级进阶之“热重载”

作者头像
CC老师
发布2022-01-14 14:49:42
4510
发布2022-01-14 14:49:42
举报

“热重载”机制极大的提高了我们的开发效率,也越来越受开发者青睐,这个词出现的频率也越来越高,他最初是前端开发中的概念,慢慢延伸到跨平台,甚至原生开发,比如Vuex、Flutter等,热重载这个机制非常好用。

我们在前端开发的过程中改动任意一点点代码,保存之后,立即就可以显示出效果,界面一点点的微调很快就能搞定,不用跟我们iOS开发一样,如果平时使用StoryBoard搭建界面,就需要重新编译,运行,项目比较庞大的话,一点点的页面样式改动都需要等待很长的时间来编译运行。

其实,StoryBoard也可以实现所谓的“热重载”,但是知道这种用法的开发者少之又少,苹果在iOS8就发布了这种新特性,也就是在2014年,已经过去非常久了,我再来炒一次剩饭,让大家都能学会这种“高级”的用法。

StoryBoard中的热重载,主要就在于关键字IB_DESIGNABLE的使用,而这个关键字,和关键字IBInspectable是一同发布的,我就顺带一起来介绍,而且他们搭配起来使用会更加爽滑,接下来我就通过一个小demo来详细演示一下,首先在空白的ViewController里面拉一个UIView进来,固定宽高,拉好约束,然后给一个背景颜色,如下图。

我们知道,Identity Inspector里面有一个User Defined Runtime Attributes(如下图),在这个里面,我可以通过runtime的机制,去使用KeyPath来动态的添加我们需要的额外的属性和值,比如添加圆角、添加阴影的偏移、添加边框等。

但这些都是layer才有的属性,并没有提供给UIView,所以我在Attributes Inspector里面是没有办法设置的,并且,这里也不能设置边框颜色和阴影颜色,因为边框颜色和阴影颜色是CGColor对象,我在这里只能设置UIColor,肯定很多人都在这里浪费过时间。

那边框颜色和阴影颜色怎么设置呢,比如懒得折腾的话,直接拉一根IBOutlet,然后用代码去设置,也是比较常用的办法,这样虽然也能够比较简单方便的处理这个问题,但并不是一个很好的方式(如下图)。

而且通过KeyPath来添加属性特别容易导致莫名其妙的crash,如果你没有立即去运行,去及时的查看效果的话,写完这里之后,然后去改动了很多的代码,再去运行,结果崩溃了,这个时候你根本就找不到问题在哪里。

我以前就遇到过这种问题,比如我很自信,radius手敲很熟练,写完就不管了,然后去写业务逻辑代码去了,然后过了一小时,运行,哦豁,crash了,搞了好久才发现是我的radius,手抖多打了一个s。

当然,现在的Xcode版本已经不会崩溃了,之前是一直会崩溃的,苹果把他的健壮性又加强了一点,越来越方便我们开发了,但是他也没有任何的错误提示,还是有缺点的,而且我们的异常断点也断不到,也不好找问题。

所以,对于这种方式,我是比较的嗤之以鼻的,也并不推荐大家直接在这里面写,一点都不友好,还有点傻呼呼的,那有更好的办法吗,当然有,就是关键字 IBInspectable,使用这个关键字,他就可以利用运行时机制,把这些属性映射到XIB上。

同时我们UI类的自定义属性也可以映射上去,那这个关键字要怎么用呢?

我先来自定义一个UIView,创建一个子类(如下图),然后在ViewController里面再拉一个UIView,水平垂直居中,宽高固定,指定一下class。

然后在RadiusView.h文件里面,我们可以随便自定义变量名,比如,圆角、边框宽度、边框颜色、阴影颜色、阴影偏移offset,然后把IBInspectable直接放到变量前面。

保存之后,我们来看Attributes Inspector,这里就有了我刚刚写的几个变量,还是挺神奇的。

他们都是没有值的,我来随便设置一下,然后,我来看 Identity Inspector,这个User Defined Runtime Attributes里面,也有了我刚刚设置的值。

并且在这里进行Value的更改,Attributes Inspector中的值一样被改动了,这样我就实现了用更高级的方式、用可视化的方式,来设置组件本身没有的属性,完全脱离了之前手敲KeyPath的窘迫,就可以让开发变得更简单。

但是,这几个变量名,都是我自定义的,随便写的,那 Runtime 不认识我自定义的变量,运行是没有效果的,所以这个时候,我需要重写他们的 setter 方法,因为我要让 Runtime 知道,我这个变量,设置的是什么东西,我就在 .m 文件里面,稍微写两个。

这里需要注意的是,我设置圆角的时候,还要把 clipsToBounds 设为yes,防止我忘记在Attributes Inspector里面进行勾选,再来运行,就没有问题了(如下图),这里我没有实现阴影的设置,因为设置了也不会生效,由于clipsToBounds,所以阴影和圆角是不能同时设置的,这里有很多的解决方案,我就不多说了。

现在问题来了,我在这里设置了圆角和边框,我的Storyboard里面是没有变化的,还是一个方方正正的初始状态,只有运行起来才能看到效果,那我要怎么实现热重载呢,这里就来到了第二个关键字,IB_DESIGNABLE,我们通常把这个关键字放到 .h 文件的 @interface 前面(如下图)。

当然,放到 .m 文件里也是可以的,这个时候我需要说明一下,这个关键字,如果你是在M1芯片的Mac上做开发,你必须把Xcode更新到13.0及以上的版本,否则他是不起作用的,并且会给你报一个错,但是不影响运行,也不影响我使用 IBInspectable,只是热重载的效果看不到。

写完 IB_DESIGNABLE 之后,都不用保存,立马就可以看到,Xcode自动在进行一个刷新,并且,在storyboard里面,我写的圆角、边框,都出来了(如下图),这就是使用Storyboard进行的一个热重载,我在Attributes Inspector里面修改圆角或者边框的值,立马就有效果,并且用起来,真的非常爽。

当然,我也可以去手动刷新,在Editor里面,最下面找到Automatically Refresh Designable Views(如下图),取消勾选,然后需要刷新的时候,点击它下面的 Refresh All Views 就可以了。

那么我这只是搞了几个layer的属性而已,是非常简单的,如果说,我通过代码设置其他的属性,或者代码写一个UIView,能给我热重载吗,当然也可以,但是有个条件,代码必须写在drawRect方法里面,我来试一试,比如我改一个背景颜色,立马就变了,非常好用(如下图)。

我再新建一个UILable,设置一个字符串,如下图。

甚至我再绘制一个圆,都是可以的,活学活用,我把绘制圆所需要的变量,定义出来,加上关键字IBInspectable,注释掉其他的代码,如下图。

然后,我先给他们设置几个值。

然后,我在drawRect里面,来进行绘制,绘制一个圆形最方便的方式就是用贝塞尔曲线。

效果立即就显示出来了。

虽然这个效果我看着有点不舒服,怪怪的(手动狗头),先不管他吧,现在我就可以在Attributes Inspector里面来任意修改这个圆形的属性,简直very nice,好,这篇剩饭就写到这里吧。

这就是我非常喜欢的StoryBoard的使用方式,所见即所得,根本不用运行,因为storyboard里面的效果,跟运行起来是一模一样的,就可以极大的提高我们的开发效率,最后欢迎大家留言讨论,码字不易,需要鼓励。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 HelloCoder全栈小集 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档