個人 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…

相關文章
相關標籤/搜索