標籤: iOS

如何使用 PHPickerViewController 取得 PHAsset

PHPickerViewController 是系統內建的一個照片選取工具,透過 PHPickerConfiguration 設定它,然後從它的 delegate function func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) 取得用戶選取的結果。看起來非常簡單直覺,直到我踩了坑...

繼續閱讀 ➜

UIScrollView and AutoLayout

以前的作法

在以前要用 Auto Layout 來設置 UIScrollView 的 sub views 並不是一件讓人愉快的事情,雖然不複雜,但步驟就是有點麻煩。因為 scroll view 自身的特性,所以必須設定它本身的位置與尺寸,然後設定 sub views 的位置與尺寸,最後算出 contentSize 的尺寸。總結來說大概分成以下幾步:

  1. 設定 UIScrollView 本身的位置與尺寸
  2. 建立一個 contentView 並加到 UIScrollView 的 sub view
  3. 設定 contentView 的位置,通常是四邊都貼齊 UIScrollView
  4. 可以滾動的 sub views 都加到 contentView,然後用 auto layout 設定這些 sub views 的位置與尺寸
  5. 如果設定無誤的話,contentView 就可算出正確的尺寸,這就是 UIScrollViewcontentSize

最讓人困惑且忽略的就是第三點,因為它很不自然,但在 UIScrollView 卻又是必須的。另外就是第四點,一定要有明確的位置跟尺寸,這樣才有辦法算出 contentSizeUIScrollView 使用。

現在的作法

從 iOS 11 開始,UIScrollView 多了 frameLayoutGuidecontentLayoutGuide 這兩個方便的屬性,讓我們不必再用不自然的方式去設定 content 的 auto layout。

  1. 可以使用舊有的方式或是使用 frameLayoutGuide 設定 UIScrollView 本身的位置與尺寸
  2. 不需要額外的 contentView 了,直接把內容加到 sub view
  3. 這些 sub views 與 contentLayoutGuide 建立 auto layout constraints

整個設定流程變得自然許多,也更不容易出錯。現在我們只要確定 sub views 有設好明確的位置與尺寸,讓系統能夠算出 contentSize 即可。

簡介 iOS Native 與 Web 的互動方式

有的時候一些跨平台共用的頁面會使用網頁的方式打造,在 iOS 的世界裡我們可以使用 WKWebView 呈現網頁內容,除了單純的呈現之外,彼此的互動也是不可或缺的一環。這篇文章將會簡單介紹該如何達成網頁與 iOS 原生程式碼之間的雙向溝通。

繼續閱讀 ➜

watchOS app 開發筆記:Complications

這一篇主要是要紀錄如何設定 Apple Watch 的 Complication。

Complications 是錶面上可讓使用者選擇的小元件,需要使用 ClockKit 開發 (有些畫面可以用 SwiftUI 開發),它的用途是在特定的時間,顯示相對應的資訊。

Apple Watch 內建數十種錶面,每種錶面支援的 complications 數量 / 位置 / 尺寸都不盡相同,根據不同的尺寸跟風格,定義了多種不同的 families,每個 familiy 支援不同的 templates,我們使用 template 來設定要顯示的文字、圖片、或儀表圖。各種不同 families 的長相可以參考這份文件

繼續閱讀 ➜

watchOS app 開發筆記:傳遞資料

這一篇筆記主要是要記錄如何在 iPhone app 跟 watchOS app 之間傳遞資料。

iPhone 跟 Apple Watch 的溝通方式

iPhone app 跟 Watch app 可以透過設定相同的 App Group 共享檔案,也可以透過 WatchConnectivity 溝通,App Group 的方式沒什麼好說的,所以來紀錄 WatchConnectivity 的作法。它主要分為兩種方式:

繼續閱讀 ➜

整合 Unity 到 SwiftUI App

最近剛好有機會要整合 Unity 到 SwiftUI 開發的 app 裡頭,整個過程不算難,但是蠻繁瑣的。網路上的資料絕大部分都是跟 Objective-C / UIKit 的整合,比較少 Swift / SwiftUi 相關資料,所以趁著記憶猶新的時候把它記錄下來,希望可以幫助到其他人以及未來的自己。

從 Unity 2019.4 的版本開始,它提供了 UaaL (Unity as a Library) 功能,可以把 Unity 專案匯出成 framework 讓其他程式使用,開啟了原生平台與 Unity 互動的更多可能性。你可以只用 Unity 開發遊戲或其他精美畫面的部分,剩下的則是使用原生平台(例如 iOS 或 Android)開發。

我使用的開發環境是 Xcode 12.5 + Unity 2020.3.15f2 LTS,預期達成以下目標:

  1. 在 SwiftUI 顯示 Unity 的畫面
  2. iOS 跟 Unity 可以雙向傳遞訊息

先附上 sample code。這篇文章會有大量程式碼,也會假設你對 Xcode 跟 Unity 的操作有基本的認知,廢話不多說,讓我們開始吧!

繼續閱讀 ➜

What Time: 一個寫給孩子的小玩具

我的小孩逐漸長大,到了需要看得懂時鐘的年紀了,但經過多次的嘗試,無論是看圖學習或是寫練習本,他就是記不住要怎麼看指針時鐘。

還好,我是一個工程師,而且是一個會開發 iOS App 的工程師。

既然小孩會被手機 app 吸引、研究報告又證實在遊戲中學習的效果好,那我就來開發一款 app 讓孩子可以不停的練習吧。所以趁著防疫期間,我就做了一個很簡單的 app,它會隨機顯示時間,只要正確輸入顯示的時間,就會再隨機顯示另一組時間。

就是這麼簡單樸實的一個小東西,卻可以讓小孩玩得不亦樂乎,而且效果驚人,不到一個星期他已經會看時鐘了!

有興趣的人可以來這裡下載原始碼,自己安裝到手機上玩。

如何下載、安裝、管理 Xcode

下載

不要透過 AppStore,因為速度太慢太不穩定了,要去官方網站下載才快。但是我們還有更快的方法,可以透過下載軟體同時開啟多條連線下載,我推薦使用 XcodesAppDownloader-for-Apple-Developers,前者比較漂亮,後者還可以下載 WWDC 的影片。

安裝

不要直接解壓縮 xip 檔,這樣會花很長的時間。下指令去解會快很多:

xip -x Xcode.xip

管理

可以放多個不同版本的 Xcode 在 Applications 資料夾,只要名稱不一樣就好了,記得要下指令來指定要使用哪個版本。

sudo xcode-select -s /Applications/Xcode.app

時間久了之後,會產生很多沒再用的檔案佔用空間,我們可以使用 DevCleaner for XcodeXcodeCleaner-SwiftUI 來幫忙清理,效果非常的好!

參考資料

安裝 Xcode 的正確姿勢

漫談 iOS 架構:從 MVC 到 VIPER,以及 Redux

很榮幸我能在今年的 iPlayground 分享了過去幾年以來,我對於 iOS 架構的一些看法與心得,投影片由此下載,本文則是比較詳細的文字稿。

這幾年大家逐漸重視 iOS 的架構設計,從最基本的 MVC 到開始普及的 MVP / MVVM,到分工細膩的 VIPER,每個 pattern 都有擁護者;近期也有為了解決畫面轉換的 Router / Coordinator 以及為了解決資料一致性的 Redux。

我們 app 早期的架構是 MVC,後來改成 MVVM,後來為了因應複雜的流程所以引進 Coordinator,也引進 Redux 處理資料一致性的問題。

接下來會聊聊這幾種 pattern 及其演化過程。

繼續閱讀 ➜