iT邦幫忙

2018 iT 邦幫忙鐵人賽
1
Software Development

Swift 學習目標 -- 30 天送審第一支APP系列 第 33

Notification 方法實作不同 View Controller 之間傳值

  • 分享至 

  • xImage
  •  

前幾天做了個簡單的小小遊戲:玩家在 TabPageTwoVC 上與電腦廝殺,雙方初始生命值都是 210 。玩家攻擊一次電腦會減少 30 生命值,電腦攻擊一次的效果則是 1~60 的隨機數值。雙方每回合剩下的生命值則要回傳到主頁 TabPageOneVC ,並比較輸贏。

https://ithelp.ithome.com.tw/upload/images/20180225/201076940xTvh7hjbs.png
為了達到遊戲效果,我們必須讓玩家與電腦每回合剩下的生命值即時顯示到 TabPageOneVC 上,並比較生命值高低。如圖
https://ithelp.ithome.com.tw/upload/images/20180225/20107694xxVtZBABLT.png

原本考慮用比較熟悉的 delegate 方式來實現不同 VC 之間傳值,不過 delegate 偏向物件對物件之間的溝通。後來決定試試新的 Notification 作法。

參考了許多教學文(也小小撞壁了兩天),終於還是完成了:

Notification

NotificationCenter.default.addObserver
NotificationCenter.default.addObserver(observer: Any, selector: 傳值的方法, name: NSNotification.Name(rawValue: key 的名稱), object: Any?)

想像一下在我們的 TabPageTwoVC 與 TabPageOneVC,想要私下熱線。這時候,我們必須決定要兩個 VC 的哪些物件上,安裝一組電話。
在這個小遊戲裡頭,就是我們在 TabPageTwoVC 的 attack 按鈕,做為生命值的發送者 ; 以及 TabPageOneVC 上的 Game1 Player 與 Game1 CPU 兩個 label。

為了達到這個秘密熱線,我們首先要為 TabPageTwoVC 上,顯示玩家與電腦生命值 label 分別註冊一個獨一無二的 key(我自己是把他想像成是一組類似電話號碼的字串,讓擁有這個 key 的兩個物件可以互相撥打熱線) 。

使用 NotificationCenter.default.addObserver ,添加 addObserver 在我們要監聽的物件上。

NotificationCenter.default.addObserver(self, selector: #selector(passMyGameOneScoreData(myLife:)), name: NSNotification.Name(rawValue: gameOneBmooScoreKey), object: nil)
///#selector(passMyGameOneScoreData(myLife:) 是一個 func 
//rawValue 的值是我們剛剛註冊的那個 key

NotificationCenter.default.post(name: NSNotification.Name(rawValue: gameOneBmooScoreKey), object: self, userInfo: ["me": "\(String(describing: myLifeVal.text!))"])
// userInfo 的param: [AnyHashable : Any] 拿來把我們想 pass 的 data 儲存成一個 dictionary

接下來開始在接收訊息的 VC: TabPageOneVC 上添加電話(addObserver),以便接起來自 TabPageTwoVC 的熱線。

在 viewDidLoad() 裡面插入 addObserver :

        
    NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: gameOneBmooScoreKey), object: nil, queue: nil, using: catchGameOneMyNotification)

定義 catchGameOneMyNotification 這個 func :

func catchGameOneMyNotification(notification:Notification) -> Void {
        guard let score = notification.userInfo!["me"] else { return }
        print(score)
        gameOnePlayerScore.text = score as! String
    }

即可完成即時傳值的功能!

https://ithelp.ithome.com.tw/upload/images/20180225/20107694FaRZdyWlkD.png


上一篇
請求定位權限及取得目前位置
系列文
Swift 學習目標 -- 30 天送審第一支APP33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
吳晉榮
iT邦新手 5 級 ‧ 2018-03-12 22:55:20

帥耶, 老皮

ellstang iT邦新手 5 級 ‧ 2018-03-13 11:00:03 檢舉

https://ithelp.ithome.com.tw/upload/images/20180313/20107694k9HF4b70sw.png

我要留言

立即登入留言