个人 WWDC 2019 Scholarship & 来一次完整的使用 Playground(二)

原文地址:PJ 的 iOS 开发平常git

这篇文章将会在保证主体内容的完整上加入参加我本科时代最后一个比赛 Apple WWDC 2019 Scholarship 项目的完整讲解。github

前言

在上周五(15号)时,我刷着微博,忽然间看到了梁杰大大转发 AplloZhu 的一条关于 Apple 今年 WWDC Scholarship 的活动介绍。我注意看了下时间,15 号早上 8 点到 25 号早上 8 点,总共就 10 天的时间,在这个十天的时间使用 Playground 作出一个 demo。固然这里说的 demo 确定不是咱们日常作技术验证那般无所谓,要求是可以完整表达本身的创意,并结合 Apple 的相关 API 完成。markdown

大概是早上 10 点左右看到的消息,从上周五直到昨天,我整我的都处在一种十分的焦虑过程当中,这种焦虑伴随着激动和不安,几乎天天晚上都没有睡好,早上到公司时也没有任何的状态,一心想着我要怎么作好这个事情。架构

得知这个消息后,立马开始在脑海里搜寻创意,我很是明白 Apple 对创意十分看重,而后又想到这两年 Apple 对人工智能的关注几乎到了 all in 地步,因而结合 CoreML 和 AR 能作些什么呢......app

思考了二十分钟后,我完全放弃了经过技术来搜寻创意的想法。忽然灵光一闪,想到 Apple 近年来对教育和环境领域是至关重视!若是我作一个跟环境保护有关的教育项目呢?在思考的同时我又浏览了一遍 WWDC 2019 Scolarship 的 repo list,把几乎全部项目介绍中的视频都看了一遍,总结出了如下几点:性能

  • 不须要作太精美的 demo,但精美有加分;
  • 音乐若是运用不当仍是算了吧;
  • 重点在于你要表达什么,而不是你作了什么;
  • Playground 也能够没有“交互体验”,直接看运行;

这时,我悬着的心终于能够放了下来,原来并不必定要作成向 Swift Playground 中那么精美的 demo 啊!可是值得注意的是,在去年 accepted 的 repo 中,有一部分是视觉上赢了。我在想,若是我直接拼 CoreML 和 AR 等的东西实在是没发现有什么好的点子,为什么不来一个弯道超车?我也来作一个视觉上的冲击?学习

我继续在大脑里搜索,忽然!我发现了这么**“黎锦”**这个东西一直给了我很大的震撼!它不但具有对称美、粗旷的线条,甚至还有夸张的图案!在吃午餐的时候我仔仔细细的全盘推演了一遍交互,若是我可以运用得好“对称美”这个关键点,必定很赞!通过了一番修正后,决定就是这个题目了!优化

黎锦

准备工做

脑暴

午餐回来后,我开始清空大脑,放下全部其它事情,准备尽心尽力。我首先肯定了本身要作的是一个具有“对称美”的 demo,必需要围绕“对称”这个事情来展开;并且还要突出黎锦最核心的地方——粗旷的线条和夸张的图案,头脑风暴开始了......人工智能

健身完后,脑子连同身体一块轻松了,开始构思具体的交互和细节。黎锦,它的本质是纺织品,其次是黎族人对天然的崇拜的表达,最后才是工艺品,因此我最终目的也出来了:spa

  • 利用纺织品的底纹;
  • 突出黎族人的对天然崇拜的元素;
  • 尽量作的精美;
  • 利用拼图的特性。

又通过了一个多小时的时间,把一些细节的地方都完善好,并肯定本身也被本身陶醉了后,开始画原型图,下面是脑暴时的部分手稿:

手稿

原型图

临近下午六点时,终于把一些肯定的元素都完成了。不得不说这些“突出黎族人对天然崇拜的元素”实在难以搞定,单是用 Sketch 画这几个小图,一两个小时就这么过去了,下面是原型图的展现:

原型图 1

原型图 2

插一句题外话:在此我要强烈鄙视曾经的我。以往参加各类比赛时,我都对原型图嗤之以鼻,认为这部分工做毫无心义,存粹是浪费时间。但通过 BonfirePLook 这两个项目后,给我打了一个狠狠的脸!真诚的但愿你们在往后进行项目的开发工做时必定要先作好原型图。

开发

次日

整个 demo 的核心难点在今天基本上就完成了。主要是解决“对称”问题。当时我给本身下的一个死要求——不要考虑性能,缘由很简单,第一是没有时间,第二是个人运行平台为 Mac,不须要纠结这方面的问题。

镜面对称

当用户在视图虚线的左半部分拖动色块时,与之对应在屏幕右半部分的色块也会随着一块儿滑动至同等位置,且为镜面对称。这部分功能的实现比较粗暴,但实际上就是这么一回事,但在内存占用上是有至关大能够进行优化的空间,由于用户永远只能操纵左半部分的色块,而对于右半部分的色块是没法操纵的,因此位于右半部分的色块彻底能够抛去 UIResponder 等协议的遵循,仅仅只须要 CALayer 便可。

底部栏

这部分比较简单,一个 UICollectionView 便可完事,但考虑到后期组件重用问题,仍是给 UICollectionView 包了一层 UIView。到如今反过头去看,其实是没有任何须要的。

完工图

第一天完工图

第三天

今天是周日,时间比较多,开始作一些交互上的东西。

从底部栏拖拽元素至画布上

首先是从“底部栏”拖拽元素至画布上。这部分其实也还 OK,须要维护好两套坐标系的转换,用户触摸点从底部栏到画布上这一过程色块须要进行转换的坐标不能使用底部栏的坐标进行,由于色块在底部栏上的 x 和 y 都是 10 之内的数,若是还以底部栏做为坐标转换的依据,那么当用户拖拽色块时,色块会直接跑到屏幕的最上方。

所以咱们须要以底部栏的 superview 来做为坐标转换的依据,也就是 UIViewControllerview。通过一番调整后,使用了长按手势来激发拖拽功能,并增长了底部栏元素被拖拽后数据源的删除。

自动吸附

这部分 bug 比较多,直到昨天都还在维护相关逻辑。我想要达到的效果是,把画布分为 smallnormalbig 三个尺寸的大小,其中 normal 是默认大小,3 * 9 的方格充满画布。当用户把元素拖拽到画布上 touchEnded 时,若是此时元素不知足彻底嵌入离它最近的方格时,系统将自动把该元素“吸附”到距离该元素最近的方格中,下面这个动图能够比较好的进行展现:

吸附功能

当时之因此想到这个吸附功能,主要是我在玩的过程当中无法判赢~若是只是让用户去本身根据完成图的提示来进行拼图,那实在是无趣了点,要稍微的营造出一点慢慢的看出端倪,最后拼图完成后发出一声“哦!”的感叹就知足了~

占位还原

这个功能是依赖“自动吸附”的。若是用户此时拖拽了一个元素覆盖到了一个旧元素上,系统要自动把拖拽的元素还原到原来的位置上。这部分也 OK~

第四天

今天是周一,距离提交截止还有七天。

判赢

完成了以前把画布切割成不一样 size 的方块功能后,此时再来思考若是才能算赢就很简单了,由于画布自己就是一个二维列表,嗯,就是这么简单了。

在 Playground 中跑起来

以前有几回尝试使用 Playground 进行开发的糟糕体验后,此次完全放弃了使用在 Playground 开发的想法,先用写一个 app 的架构模式去完成而后再迁移到 Playground 中。

第一次迁移真是把我搞得不行~整了很久根本没跑起来。幸好有了去年的 WWDC Scholarship repo list,看了好几个 repo 后才明白是怎么个事情,第一次使用 Playground 运行项目能够参考个人这一篇文章

第四天完工图

第五天

到了今天核心功能基本上都已经完成,接下来要作的就是提高交互,尽量的作得更加精美,完善除了主流程以外的其它 case 下产生的问题。

画布大小

这部分的功能在次日的时候已经思考过了,提供了三种大小的画布尺寸,就不展开了~

其它

今天纠结错了一个点。本来想在自定义模式下提供“长方形”、“正方形”和“圆形”三种形状的画布,但却由于最初的架构问题致使一直无法完成,看着时间愈来愈短,拼图模块却一点没作~心里开始有些紧张了。今天反反复复的把时间浪费了在了修改画布形状的功能上。

进过反复修改后,终于肯定了“大力神”的定稿!我当时看到“大力神”的表情......😲

黎族守护神之一“大力神”

第六天

今天是周三,留校与毕设导师见面的日子,又多了完整的一天。给本身下了一个必须完成的任务,今天务必要完成拼图模块。

拼图模块

拼图你们都玩过,按照提示图把零散的部件拼好。我并无全盘借用拼图的全套游戏模式,而是仅仅采用了它的游戏逻辑。能够肯定的是,确定不能把画十几二十个拼图元素小图,这样不但会把人画疯并且时间会浪费得更多,再加上若是考虑到屏幕适配问题那就更痛苦了呢~

因而我想到使用 Core Graphics 的方法对一张图片按照所需尺寸进行切割,具体实现以下:

extension UIImage {
    /// 经过原图获取 rect 大小的图片
    func image(with rect: CGRect) -> UIImage {
        let scale = UIScreen.main.scale
        let x = rect.origin.x * scale
        let y = rect.origin.y * scale
        let w = rect.size.width * scale
        let h = rect.size.height * scale
        let finalRect = CGRect(x: x, y: y, width: w, height: h)
        
        let originImageRef = self.cgImage
        let finanImageRef = originImageRef!.cropping(to: finalRect)
        let finanImage = UIImage(cgImage: finanImageRef!, scale: scale, orientation: .up)

        return finanImage
    }
}
复制代码

经过以上方法,我就达到了只须要经过一些简单的数学计算就能够根据用户当前设置 sizeType 类型来控制单个拼图元素的大小~

拼图完成

若是用户都按照拼图的实际位置放置好了,实际上就是赢了~但当我写完这部分的逻辑后,看到最终的成果图,总感受哪里不对劲。

奇怪的拼图完成图

对比了之后发现!woc???怎么两个头?反复查看取拼图元素的逻辑代码后,发现原来是这么一回事......

我在代码中写的是从每行 x=0 处开始日后取 item=62.5 宽度的图,连续取三个,但 iPhone 7 的屏幕宽度为 375,一半就是 187.5,三个 62.5 就是 187.5 这没啥问题,但问题出在个人图是否是标准的 750 * 1334,而是 647 * 1159,因此这就致使会多日后截取的问题。不想改图稍微改动了下相关位置逻辑完事。(其实应该把图改了)

给拼图完成后加了一点彩纸动效和背景音乐,但背景音乐不知为什么在 Playground 中只“滴”的一下就没有下文了,彩纸动效以下:

彩纸动效

第七天

今天一直在维护拼图逻辑,想着赶忙把拼图作完,而后立马开始作自定义部分。

第八天

今天是周五,学校下午开了个年级会,又多了完整的一天。今天必定要完成自定义模块,而后明天开始写各类文案。

自定义模块

完成了拼图部分后,自定义就很简单了,剔除判赢、自动吸附和裁切元素三个大头,加上一些好看的元素替换到底部栏中的拼图部分中的元素便可。但由于是用户自定义部分,要提供必定的个性化功能,由于今天已经周五了,好多文案也没写,想着那就完成“删除”和“旋转”两个功能好了~

  • 删除。再次使用长按手势完成,稍微啰嗦一点的地方在于各类数据源的删除和恢复的维护逻辑。
  • 旋转。使用了双击手势。考虑到用户在 Playground 中使用旋转手势实在是难以操做而作出选择。在实现旋转的过程当中,也要时刻保持旋转后的镜面对称,不能只是简单的 currentItem.transform = copyItem.transform 这般简单了。须要根据不一样的状况作几个取反操做再赋值。

第九天

到了今天不知为什么毫无动力,已经没有再继续开发和优化下去的欲望了,只想着快点结束。只对用户自定义部分新增了几个新资源后就结束了所有的开发工做,开始写 Playground。

Playground

我给你们一个建议:开两个工程,一个是以 app 的模式来进行开发的工程,一个是 Playground 工程。写完 app 一个功能后就立马在 Playground 中进行复现,直到复现成功且功能正常后,再继续写 app。这样你会爽得飞起。

固然,Apple 给了一个 PlaygroundBook 的模版工程,能够根据这个工程来进行修改。

Playground 遵循大部分的 Markdown 语法,以下图所示:

Xcode markdown

须要注意的是:

  1. 使用 //: [Previous: The First Part](@previous) 返回上一个 Page,使用 //: [Let's get the first part!](@next) 进入下一个 page,目前来看只能作顺序跳转,若是是纯英文命名的 page file,排序是按照字母序来进行的(差点被坑)。推荐在命名前加上 123 来进行标识。
  2. 在 Page 中进行任何一行代码修改都会触发 liveView 从新构建。若是你不想维护一个全局对象,能够尝试使用个人这种作法经过全局与用户进行交互:
import UIKit
import PlaygroundSupport

public var brocadeType: PJHomeViewController.BrocadeType = .normal
public var brocadeBackgroundColor: UIColor = UIColor.bgColor()

public func start(_ gameType: PJHomeViewController.GameType) {
    let vc = PJHomeViewController()
    vc.brocadeType = brocadeType
    vc.gameType = gameType
    vc.brocadeBackgroundColor = brocadeBackgroundColor
    PlaygroundPage.current.liveView = vc
}
复制代码
  1. 一个 Page 都会有一个独立的 liveView,多个 page 之间互不干扰,因此尽可能让多个 page 之间不要产生关联。
  2. 每一个 page 的 liveView 的 frame 很怪异,不推荐用 UIScreen.main.bounds 的方式获取屏幕宽高,由于这会获取到当前 Playground 所运行平台的屏幕宽高,在 Mac 上这屏幕的宽高就很酸爽了,记住这只是个 demo,屏幕适配的时机不适合如今。

Submission

一切完成后,就要开始写文案了,今年的 WWDC Scholarship 能够写如下文案:

  • 介绍你本身是怎么学习计算机的;
  • 介绍这个 Playground 中运用到哪些技术以及功能点;
  • 若是你有本身的独立开发的 App,能够介绍一下;
  • 若是你还有什么想让 Apple 知道的,能够说一下;
  • 超过十八岁能够把本身的简历附上去。

我很是的后悔本身在大学四年中没有开发出任何一款彻底属于本身的 App,我昨天有点微微难受。但愿接下来的毕设可以给本身一些安慰吧~

简历我没有附,虽然 Apple 明确表示简历不会影响最终的评分,但我仍是不想。

结束了

当我按下 Submit 时,整我的彻底放松下来了......

世间还有这么多美好的事物,我为何要和本身这么过不去?整整一周的时间整我的的心情都是紧张的,前两三天的时候一直在担忧东西作不完,作的很差,还有多少功能没有实现。但到按下 Submit 后,管它还有什么没作完,也无论最后究竟是能不能被选上,只想远离这个位置。去呼吸新鲜空气,去看这蓝天白云,去看这纷繁多彩。

本来打算蒙头盖被睡一觉,但不知为什么心情又开始剧烈激动起来,翻来覆去睡不着,买了张《波西米亚狂想曲》的电影票,在电影院里一我的吃着鸡米花,享受着这视听盛宴,真好!

Playground 工程:github.com/windstormey… App 工程(你能够听到独特的黎族歌曲):github.com/windstormey…

相关文章
相关标签/搜索