iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 9
0
Software Development

Swift零基礎實作旅遊景點app系列 第 9

Swift從零開始-Day9:NavigationController基礎學習

  • 分享至 

  • xImage
  •  

分類:UIKit學習

1. 介面建立方法

1-1. 以元件庫來製作介面

方法1:

將許多ViewController拉到main.storyboard,之後以拖拉的方式將要實現Segue的元件拉到要進行segue的ViewController,選Action Segue -> Show 。註:此法如果沒有特別設定則在導覽時會是由下往上轉換畫面。
/下列兩個方法可以不用特別設定就產生橫向導覽的型態/

方法2:

選擇Editor -> Embed in -> Navigation Controller 。

方法3:

直接在右下方選取Navigation Controller,之後可先把預設的Table View Controller先刪掉,然後從Navigation Controller按住Control拖拉到新的ViewController,然後選root view controller。註:Navigation Controller 包住的第一個ViewController稱為“ root view controller”。
註1:方法2與3產生的畫面上面會產生一navigation bar,若要在上面新增按鈕,要選Bar Button Item(不是選Button)。
註2:於navigation bar可以設定title(預設只有root view controller可以直接設定),其他的畫面必須再拉進元件Navigation Item。

全部做好後的結果

1-2. 以storyBoard ID來進行介面的切換

  • 先建立ViewController的storyboard ID
  • 程式碼:下面程式碼目的是按下一個按鈕後進到下一個畫面
import UIKit

class ViewController: UIViewController {

    @IBAction func gotoView2(_ sender: UIButton) {
        let lightRed = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "lightRed")
 //用class UIStroyboard的instantiateViewController方法可以初始化出一個UIViewController,在withIdentifier填入剛剛設定的storyboard ID,並將此UIViewController實體化存進lightRed這個常數    
        // present(lightRed, animated: true, completion: nil) 
//將lightRed這個ViewController呈現出來,但這樣會讓轉場是從下到上
        /*想讓轉場為橫向的,但要這樣做必須先將第一個畫面embed in 到navigation viewController*/
      self.navigationController?.pushViewController(lightRed, animated: true) //此行意義用self.navigationController回到包著我的navigationController(型別為class UINavigationController),再利用UINavigationController中apple內建的方法pushViewController,推到我們設定所要的ViewController(利用storyboardID推)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}* 
  • 回到上一個畫面:雖然已經有navigation bar系統生成的back回到上一個畫面,但下面的程式碼是假設新增一個按鈕來回到上一個畫面。
import UIKit
class LightGreenViewController: UIViewController {

    @IBAction func backtoView2(_ sender: UIButton) {
       // self.navigationController?.popViewController(animated: true) //此行意義用self.navigationController回到包著我的navigationController(型別為class UINavigationController),再利用UINavigationController中apple內建的方法popViewController回到上一個畫面
 self.navigationController?.popToRootViewController(animated: true) //回到第一個畫面
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

註:注意到從lightRed要到lightGreen採用橫向切換,因此有此行程式碼*self.navigationController?.pushViewController(lightRed, animated: true) -> 推出下一個畫面
而從lightGreen回到lightRed我們採用下述程式碼
*self.navigationController?.popViewController(animated: true)*
但如果現在從lightRed到lightGreen不是採用橫向轉場,而是縱向轉場
*present(lightRed, animated: true, completion: nil)* ,沒有推出下一個畫面而是用呈現的,這樣會連帶影響lightGreen回到lightRed的程式碼*self.navigationController?.popViewController(animated: true)*失效。
解決方法是用dismiss方法:dismiss(animated: true, completion: nil)取代上面的程式碼,但這樣轉場都會變成縱向的

1-3. 以Segue來切換畫面

  • 以拖拉的方式拉到連結的ViewController,選Manual Segue -> Show,建立出Segue(畫面與畫面間的箭頭)。
  • 定義Segue的ID:選到Segue -> 右上方的identifier輸入ID。

  • 將要觸發可以切換畫面的元件,輸入內建的方法performSegue(withIdentifier: String, sender: <#T##Any?#>),其中Identifier填入剛剛的ID,sender是要傳的參數,此方法預設的轉場方式是由下至上。如果要橫向轉場,將第一個畫面Embed in到Navigation Controller。

2. 畫面間的傳值

2-1. 從前面的畫面傳值到後面的畫面(正向傳值)

  • 先在後面的畫面設定一變數用來接收前面的畫面過來的值,EX: var infoFromViewOne:String? ,為了讓值從第一個畫面傳到第二個畫面而設定的。
  • 設定performSegue的sender,EX:performSegue(withIdentifier: "自己設定的", sender: myInput /*傳出myInput這個資料出去*/)
  • 覆寫方法於前面的畫面: override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    練習:在第一個畫面的文字輸入框輸入1~10的數字來改變第二個畫面對應的背景照片。

GitHub位置:https://github.com/ethan510010/SceneChangeWithNavigation.git

2-2. 從後面的畫面傳值到前面的畫面(反向傳值)(假定為兩個畫面)

  • 反向傳值需要用到protocol的概念。
  • 於第二個畫面自定一Protocol,並設定一屬性,此屬性為遵守此Protocol的類別。
  • 讓第一個畫面遵守此協定,並實作協定中的方法。
  • 讓第一個畫面當成第二個畫面的delegate。
    練習:第二個畫面選擇一個Picker來改變第一個畫面的背景。

GitHub位置:GitHub - ethan510010/ScenePicker


上一篇
Swift從零開始-Day8:多頁面Tab bar基礎學習
下一篇
Swift從零開始-Day10:UITableView延伸學習
系列文
Swift零基礎實作旅遊景點app30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言