iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
Software Development

iOS 學習筆記系列 第 7

Day07 UIKit 06 - 在 Storyboard 上設計多頁面

記得前面講過,Storyboard 裡面可以放置多個頁面(ViewController),頁面之間的跳轉關係也可以在storyboard 裡面定義,接下來我們就來介紹如何在 Storyboard 上設計多頁面

使用 Storyboard 時,我們先來對場景(scene)以及 Segues 來做介紹,在 Storyboard 中,一個場景對應一個在畫面上的內容(如一個ViewController),Segue 則是位於兩個場景間,表示從一個場景轉場至另一個場景

以下就讓我們來做一個多頁面的範例:

首先點選在Xcode 右上角的元件庫(+)按鈕來顯示元件庫,搜尋ViewController 並將其拉入 storyboard 裡面

https://ithelp.ithome.com.tw/upload/images/20210922/20118479hz4yDjPPe8.png

此時我們需要建立一個UIViewController檔,來給我們新建立的ViewController 連結,像是Storyboard 上預設的 ViewController 便已經預設與建專案時產生的ViewController.swift連結,方便我們之後能對其畫面做處理

點擊Xcode 上的 File → New → File...
https://ithelp.ithome.com.tw/upload/images/20210922/201184795T0yBdT6eu.png

選擇 Cocoa Touch Class 再點 Next
https://ithelp.ithome.com.tw/upload/images/20210922/20118479I4xwjVmXch.png

設定類別名字後選擇UIViewController 作為父類別再按 Next
https://ithelp.ithome.com.tw/upload/images/20210922/20118479LZcYbM6yOz.png

然後在檢查欲建立的路徑後按 Create,就建立ViewController成功了
https://ithelp.ithome.com.tw/upload/images/20210922/20118479FkseO0QbAZ.png

最後我們需要把剛建立的SecondViewController.swift,與之前在 StoryBoard 上建立的ViewController 做連結,讓我們點擊 Main.StoryBoard,並選取之前建立的ViewController
https://ithelp.ithome.com.tw/upload/images/20210922/20118479b8ocuYTpR0.png

然後在Xcode 工具區( Utility Area )下點選 Identity Inspector,並在Class 欄位選擇我們剛剛建立的的SecondViewController.swift就完成連結了
https://ithelp.ithome.com.tw/upload/images/20210922/201184790UvdKyZEIR.png

接下來我們可以對SecondViewController.swift設計UI,並透過之前介紹的 Assistant Editor 直接產生介面元件所需的程式碼

接下來我們要在 Storyboard 建立Segue,我們對著第一個 ViewController 按下control + 滑鼠左鍵或是滑鼠右鍵後拖曳到SecondViewController(在 Storyboard 上直接進行操作 或 在 Storyboard 項目工作區操作皆可,且可互相操作,如下)

https://ithelp.ithome.com.tw/upload/images/20210922/20118479unvqRLY0w9.png

https://ithelp.ithome.com.tw/upload/images/20210922/20118479tPPPSll4hL.png

https://ithelp.ithome.com.tw/upload/images/20210922/20118479Z3KBtUHIRq.png

然後在出現的選單裡選擇Show

https://ithelp.ithome.com.tw/upload/images/20210922/20118479zSAPJZvuJe.png

補充:
Segue可以由不同的地方做觸發,等專案之後變更複雜時,不同 ViewController 之間的Segue將不只有一個而已,因此,我們要為Segue個別加上唯一的識別碼identifier,而這個識別碼在程式中就是與其他的Segue做區分用的字串

之後有需求時,會在不同的 ViewController 使用 Segue進行資料的傳遞,Segue管理 ViewController 間的轉場,以及在轉場間所包含的 ViewController。而當Segue被觸發後,ViewController 轉場發生前,Storyboard 在執行期間會透過呼叫其prepare(for:sender:)方法來通知此 ViewController,預設的prepare(for:sender:)方法不會執行任何事,不過我們可以透過覆寫此方法來將原本頁面 ViewController 的資料傳遞至新的頁面 ViewController

接下來如上面補充所說的,我們要幫Segue設定識別碼,先在 Storyboard 上選取剛剛建立的Segue(如下圖,可直接點選 ViewController 間的Segue或是在第一個ViewController 場景裡的Segue

https://ithelp.ithome.com.tw/upload/images/20210922/20118479Uwf4OgZpGt.png

然後在工具區( Utility Area )下點選屬性檢閱器( Attributes Inspector ),並在 identifier 欄位為 Segue 設名字

https://ithelp.ithome.com.tw/upload/images/20210922/20118479HCf4O00khb.png

接下來我們將對第一個 ViewController 做跳轉到 SecondViewController 的程式編寫,我們在之前建立的按鈕點擊事件上,新增以下程式碼,讓我們按下按鈕時,會去執行我們剛剛設定的Segue來跳轉到 SecondViewController 頁

    @IBAction func buttonPressed(_ sender: Any) {
        self.performSegue(withIdentifier: "showSecondPage", sender: self)
    }

接著如果有要傳遞資訊至 SecondViewController 的話,我們先在 SecondViewController 設一個變數去接傳來的值,並讓的SecondViewController 的 Label 文字更換為傳來的字串

class SecondViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    var textForLabel = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        label.text = textForLabel
    }

}

最後當Segue被觸發後,第一個 ViewController 轉場發生前,其prepare(for:sender:)方法將會被呼叫,而我們要透過覆寫此方法來將第一個 ViewController 的資料傳遞至 SecondViewController

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showSecondPage" {
            if let secondViewController = segue.destination as? SecondViewController {
                secondViewController.textForLabel = "Hello world"
            }
        }
    }

這樣我們就成功完成頁面間傳遞資料了

至於要如何返回上一頁呢?

我們前面是透過在第一個 ViewController 建立一個Segue來實現跳轉去 SecondViewController,那麼要返回至第一個 ViewController 的話,我們就要在第一個 ViewController 上解除UnwindSegue來回到第一個 ViewController

在 SecondViewController 先定義一個要傳回去的值

    var dataPassed = "Pass something back"

在第一個 ViewController 下定義 Unwind Segue 要連結的方法 unwindToThisView(segue:)

    @IBAction func unwindToThisView(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.source as? SecondViewController {
        // 收到傳回來的值後要做的動作
            passedBackLabel.text = sourceViewController.dataPassed
        }
    }

之後要在 Storyboard 上選取 SecondViewController 來與 Unwind Segue (即剛剛的unwindToThisView)連結,這邊在 SecondViewController 上透過按鈕來操作(如下圖,連結方式同之前 建立Segue,進行拖曳,只是改拖曳至 Exit )

https://ithelp.ithome.com.tw/upload/images/20210922/20118479UE7TsWSqmB.png

https://ithelp.ithome.com.tw/upload/images/20210922/20118479xPWNXtCI4r.png

然後在跳出來的選擇清單選我們剛剛建立的 Unwind Segue 方法
這樣我們就完成多頁面的設計以及之間的互動了


上一篇
Day06 UIKit 05 - 純代碼編寫 Code
下一篇
Day08 SwiftUI 01 - Life Cycle : UIKit App Delegate
系列文
iOS 學習筆記30

尚未有邦友留言

立即登入留言