WWDC20 10649 为 Xcode Library 添加自定义 views 和 modifiers

首发于 https://xiaozhuanlan.com/topic/6920751348

前言

Xcode Library 最早是作为 Storyboard (xib)的配套功能引入。在制作 Storyboard 时,开发者打开右下角的 Object Library,从中选择合适的组件,通过拖拽快速引入组件对象。它和所有可视化搭建系统一样,是组件展示区,方便开发者快速浏览引入。后面的 Xcode 版本慢慢引入了色盘、图片资源等功能,到 Xcode10 时, Object Library 的重要性进一步提高,位置从右下角可能被隐藏的位置提升到 Xcode 右上角功能 toolbar 按钮区,常驻界面。到了 Xcode11, Object Library 升级为 Library,成为添加某些对象等的总入口,包括代码片段、文档。

很多人没有意识到,Library 其实是上下文相关,例如如果你在编辑 Storyboard 则显示 Object、Color、Image Library,

image
;如果正在选中 xproj 文件,则显示添加 Capability 快捷入口,
image
;选中 .swift 源文件,则显示 Views、Code Snippets等
image

Xcode Libary 提供了一种发现学习可视化操作视图、组件、应用 api 的快捷途径。它左侧列表展示 Libary 所有可用对象等,选中后在右侧会展示相应的文档说明和举例;顶部提供了快速搜索,支持模糊查询和组合查询,非常的高效。

总之,打开 Library “+”(快捷键- Shift + Command + L)逐渐进化为搜索、引用的总入口,如同 macOS 上的 Alfred、Sublime Text 里的 Shift + Command + P一样。

小贴士:引入 Library 里的 Object 到文件有两种方式,1. 拖拽至目标位置;2.放置光标在目标位置,双击 Object。

SwiftUI 开发过程中常用的 View 和 Modifier 如果被添加到 Library 将极大的提高开发效率,在 Xcode 11 里你可以添加自定义 Code Snippet,但不能新增新的 Object,在 Xcode 12 你可以在 View Library 下添加自定义的 View。下面演示如何添加自定义 View 和自定义 Modifier。

准备工作

为了演示效果,我编写一个简单的列表页展示近期可能上映的 5 部电影,分别显示上映电影名称、时长、片子类型,其中如果是恐怖片、悬疑片、科幻片则显示红心,表示很期待。详细代码见附件,最终效果如下;


image

理念

SwiftUI 面世之初,它的设计理念贯彻着代码即原型——开发者的代码即时预览在 Canvas 里,可作为 App 原型呈现给产品、交互作为具象参考;Xcode 12 之后,又带来了代码即文档,代码即 demo 新体验。在 Library 里自定义 view 的增减变动和代码实现、文档变动,时刻保持最新。在日常开发者,经常会遇到第三方库的开发文档、注释过时的情况。举个我最近遇到的例子,我从腾讯云下载的 OCR demo 里使用的 SDK 和他单独提供最新版本的 OCR 版本就不一样,开发文档也是旧的没更新。
使用 Library 添加 SwiftUI 自定义组件、接口说明,就不会有这种情况出现。

提炼公用 view 组件

虽然本 session 里强调是容许在工程开始之初,不需要编译,就可以创建 Library 对象,但是实际情况大部分都是重构的时候,发现某些元素是公用组件,然后提炼出来,添加到 Library,方便后续开发使用。在本文里,我们假设两种“最爱”的红心是公用组件。现在我们准备把他们添加到 Library 里。

创建自定义 LibraryContentProvider

LibraryContentProvider是 Protocol,Xcode 会扫描当前 project/workspace/Swift Pacage 所有文件里的 LibraryContentProvider 实例,添加到 Library 里。语法如下:

struct SimpleFavoriteContent: LibraryContentProvider {
    @LibraryContentBuilder
    var views: [LibraryItem] {
        LibraryItem(
            HStack{
                Spacer()
                Image(systemName: "heart.fill").foregroundColor(.red)
            },
            title: "Red heart in right",
            category: .control
        )
    }
}

其中 category 是为了在打开的 Library 左侧列表中分组;title 是对组件的描述,用来做不同组件区分。可惜的是,我们的自定义组件,选中后右侧没有显示对应的代码示例,而系统内置的 View 是有的。查阅了 LibraryItem 的接口,没有找到可定义的地方。添加完毕之后和实现的效果如图。


image

小贴士: title 不要用中文,搜索起来不方便。

创建自定义 Modifier

相比自定义 View,Modifier 可能的数量会非常多,也是最可能玩出花的地方。为了展示,我引入了 SwiftUI-CSS 库,核心代码如下(详细代码见 demo)

// 定义评论的样式
let comments_clsName = CSSStyle([
    .font(.footnote),
    .paddingEdges([.top], 2.0),
    .foregroundColor(.blue)
])
// 引用样式
Text("“\(m.comments!)“").addClassName(comments_clsName)

在 session 的举例中,是为 Image 添加了个 extension ,新增一个方法设置样式,然后将此方法设置为 Modifier Library 对象。本文我们用 SwiftUI-CSS 来设置样式,其代码添加到 Library。自定义 View 和 Modifier 的接口方式不一样。一个是属性,一个是 function 回调,因为 Modifier 需要传入参数,而自定义 View 不需要。
以下是添加自定义 Modifier 的步骤,新建 func modifiers,设置 title 和 category。

@LibraryContentBuilder
    func modifiers(base: Text) -> [LibraryItem] {
        LibraryItem(
            base.addClassName(comments_clsName),
            title: "Comment style",
            category: .effect
        )
    }

添加完毕的效果:

image

可以看到,同样比较遗憾的是,无法添加注释和示例(系统的是有的)。LibraryItem 里的 category 属性,如果是自定义 Modifier 则设置为.control 是无效的。

至此,如何添加自定义 View 和 Modifier 已经演示完了。这里有几个问题,目前 Library 还没很好支持的。

  1. 自定义 Modifier 和 View 都无法添加注释和代码样例
  2. 两个相近的自定义 View (例如,我们在编写基于 tableView 的界面时,需要设置 Cell 的 style , UITableViewCellStyleValue1 和 UITableViewCellStyleValue2 两种),你每次使用时,是不是都会很犹豫,到底用哪个?,如果自定义 View 能够在 Library 右侧顶部能够显示,该 View 的预览图是不是更好、更直观?另外 Library 声称不需要整个项目能够 run 起来就可以添加到 Library,其实是个不好的妥协。就应该把 Library 作为可预览前置条件的一部分。我画个假想图;


    image

    image

LibraryContentProvider 作为开发阶段工具链的一部分代码,通过上传到 git,可以形成大家共用的组件库;良好定义的 Modifier 可以组装成一致的视觉样式系统,提升视觉稿实现代码的速度和视觉还原度。而且在 release 包里这些开发工具链上的代码内容都会被删除。

更进一步,所有从 Swift Package 里定义的 LibraryContentProvider 子类(View 和 Modifier)都会显示在 Xcode Library 里,这是一种简单的引用第三方组件、样式的途径,非常棒。总之,善用 Xcode Library 可加速开发效能,大家用起来吧。

参考

  1. https://stackoverflow.com/questions/50962797/where-did-the-object-library-go-in-xcode-10
  2. https://github.com/hite/swiftui-css
  3. https://github.com/hite/WWDC20
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342