iOS today extension (swift) 教學筆記

iOS的「今日小工具」(today widget)的用法

Big N
Big N
Jun 18, 2018 · 9 min read

使用語言: Swift4,XCode版本: 9.4,模擬器版本: iOS11

today extension是iOS8就有的東西,不過之前一直沒用到

近期想寫個待辦事項的app,那就順便練習一下today widget吧

此筆記為記錄以下功能

1. 怎麼從專案中新增today widget

2. today extension的UI

3. today伸縮的按鈕

4. 從today中啟動App

5. today widget與APP之類如何傳遞資料(UserDefault)

1. 怎麼從專案中新增today widget

首先先新增一個空白專案

接下來再新增一個target(File -> New -> Target)

再選擇Today Extension,會發現裡頭非常多extension種類,可以善用filter,直接打上「today」就只剩一個了(請見附圖)

選擇today,再點選「Next」後會出現詢問視窗,直接點選「Activate」即可

新增完畢

這時候會發現專案的資料夾不一樣,而且執行的App的圖示也不同。

由這種資料夾分類方式也可看出,Apple不希望開發者把兩個搞混在一起。

App為一包資料夾,而Widget又是另外一包資料夾,其中Storyboard也是分開的。

基本上可以把App與Widget想成是兩件不一樣的事,這樣開發的時候比較不會有「啊~~怎麼傳個東西這麼麻煩」的感覺

如果你從E直接執行,就會發現畫面是停在Today的小工具頁。畫面應該會如下圖,有一個Widget,並且內容是白字的Hello World

2. today extension的UI

打開Widget的Storyboard,你可以發現只有一個ViewController,並且畫面超級小,也看不到那個Label在哪。

原因是Label預設是白字的(所以你執行起來才會看到白字的Hello World),而背景Default是透明,所以你是看不到Label的。

你可以先把ViewController放大(標示4、5處),你可以直接把Freeform改成Fix,這樣畫面就清楚多了,再將Label改成黑字

Apple滿建議直接用Autolayout的,因此就像你平常一樣使用Storyboard的方式一樣操作吧。

注意事項

比較要注意的是Widget並不建議使用滾動(你故意用也可以,你就會發現怎麼沒有正常滾動)。

也就是說ScrollView / TableView / CollectionView / Slider…這種東西都不能用,其實也是很好理解的,畢竟Today可以新增非常多個Widget,萬一每個Widget都可以上下滑,使用者就崩潰了;同理左右滑也一樣,到底是滑Widget還是在滑App的左右頁呢?

除了滑算以外,不應該有任何需要「輸入」的操作,也就是說不該發生彈出鍵盤的操作,也很好理解,大多使用者已經習慣「點畫面任一處,即縮下鍵盤」,但畫面通通都是Widget,點下去多半會觸發其它動作,這樣會非常容易讓使用者崩潰。

因此要記得「不要使用到任何操作滑動的元件」以及「不要輸入的操作」。

3. today伸縮的按鈕

如果有在用Today Widget的話,應該會注意到有些App可以切換展開與折合模式。(顯示更多 / 顯示更少)

這邊需要寫到程式碼,在Widget資料夾的TodayViewController中新增以下程式碼

下圖中的標號「3」(或見16行),以及標號「4」(或見20~25行)

寫了標號「3」,直接執行你會發現有出現按鈕,按了卻不會有反應

需要標號「4」,寫出模式改變時,整體的大小也需要改變,其中第22行我寫了高度要500,其實他有限制最大高度,似乎就是「手機的最大高度」,也就是就算我寫了「9999」,他也就只有手機那麼高而已了。

另外可以注意到第12行,他除了繼承一般的UIViewController以外,也有NCWidgetProviding,所以才有標題「3、4」這兩種方法。

附上程式碼,比較方便貼(貼上XCode後,再將貼上的程式碼反白選取,並且按下control+I即可自動縮排)

4. 從today中啟動App

接下來,我們直接在Widget的Storyboard直接新增一個按鈕,並且拉線,準備要做點按鈕,開啟App的行為。

在寫程式之前,必須先新增Schemes,請參考以下附圖的標號順序

第6步的URL Scheme請你自己記好你寫的

接下來再回到TodayViewController,在IBAction點下的動作中寫下以下程式碼

要注意的是url是「YOUR_SCHEMES://」,不要貼的太開心,只貼到「SCHEMES」,否則點下按鈕會出現以下錯誤訊息

他會說找不到你要他開啟的Url

一樣,附上程式碼比較好貼

點下去之後應該就會出現一片白,是正常的。畢竟我們App自從新增專案後,就再也沒有去修改,因此預設畫面的確是全白。

5. today widget與APP之類如何傳遞資料(UserDefault)

這邊先介紹UserDefault,CoreData需要研究一下3口3

首先,先拉元件。

我們在App在Storyboard拉出TextField以及按鈕,按鈕負責存下TextField所輸入的內容;並在Widget的Storyboard中拉出一個Label,負責顯示App中所儲存的內容。

再來,需要讓App與Widget互相認識。

請參考以下附圖的標號流程操作,簡言之就是去把App Groups打開並新增Groups。

這裡有兩點要注意

  1. 點選標號6的「+」後,AppGroup的名稱不是隨便亂打,是打你的bundleID,bundleID可參考下圖標號流程

2.我框選的那兩個打勾圖示,是因為我這次做這個功能時,剛好Apple權限有修改,因此他原本是出現錯誤提示的。這時候只要去Itunes點選同意權限即可。

接下來,新增完App的Groups之後,一樣Widget也要重複操作一次。請參考下圖標號順序操作。這時候你應該不需要再打一次BundleID,而是可以直接勾選了。

好了,以上步驟即可完成讓他們互相認識的依據了。

最後,寫程式

分成兩部份,分法同UI,一個是App;另一個是Widget

先是App類,

在15行全域的部份先宣告UserDefault,其中要注意的是suitName就是你剛剛寫的AppGroup,並不是亂打的。

接下來IBAction的點選就負責把資料存起來。

一樣,附上程式碼比較好貼

App部份即完成了。

再來是Widget部份

基本上是跟App一樣的,開一個全域的UserDefault,接下來畫面要出現時再讀出UserDefault所儲存的內容。

直接執行後,即可完成。

碼農勤耕田

python / swift / deepLearning

Big N

Written by

Big N

(1.01)³⁶⁵ = 37.8; (0.99)³⁶⁵ = 0.03; 每天多踩一個坑, 一年之後就變成坑王了!!! ;但是每天少踩一個坑…身體就會很變乾淨哦A口A(咦?)

碼農勤耕田

python / swift / deepLearning

Big N

Written by

Big N

(1.01)³⁶⁵ = 37.8; (0.99)³⁶⁵ = 0.03; 每天多踩一個坑, 一年之後就變成坑王了!!! ;但是每天少踩一個坑…身體就會很變乾淨哦A口A(咦?)

碼農勤耕田

python / swift / deepLearning

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store