iOS Storyboard入門及一些高階使用

swordjoy發表於2018-02-01

一、前言

Swift版本 4.0

Xcode版本 9.2

這周本來我是想要寫其他知識的,但在構建 Demo 工程的時候, 我情不自禁的就使用了 Storyboard (下面簡稱 SB ),或者說是 Interface Builder (下面簡稱 IB),所以就想著寫一篇相關文章。

這裡不討論使用這種方式的好壞,大家仁者見仁,智者見智,貓神的文章連結在後記裡面,我的觀點和他一致。


二、Storyboard基礎

這部分針對完全沒用過 SB 的讀者,極其基礎,熟悉的直接跳過!

2.1 完成目標的概覽

下面是我這一小節需要完成目標的樣子,一個遊戲的展示介面和新增遊戲。

iOS Storyboard入門及一些高階使用


2.2 介面初識

先建立一個 Demo 專案,點選 Main.storyboard 出現如下介面:

iOS Storyboard入門及一些高階使用

首先需要了解 SB 中幾個重要的區域,這裡是按照我的理解取的名字,只是簡單說明區域的作用,後面會詳細使用這幾個區域,如上圖所示:

  • 1、選單導航區域,新增的控制器、控制器之間的跳轉 Segue 及控制器上面的控制元件和佈局等等資訊都在這裡顯示。
  • 2、工作展示區域: 可以在這裡給各個控制器新增控制元件和預覽佈局後的控制元件。
  • 3、配置區域: 可以在這裡將 SB 和程式碼檔案關聯和檢視關聯後的資訊,也可以直接在這裡配置控制元件的屬性等等。
  • 4、佈局區域: 上面面有很多機型選擇,可以直接選擇機型和方向,區域2會根據選擇的機型和自動佈局直接預覽控制元件顯示的效果和佈局,中間的加減符號可以放大和縮小區域2中的內容,右上角的幾個按鈕可以進行自動佈局操作。
  • 5、控制元件區域,我們可以直接在這裡選擇控制元件,然後拖入區域2中。

細心的讀者可能會發現,區域1中,控制器在一個 scene 的下面,在 SB 中,scene 就對應著一個控制器。區域2裡面還有一個灰色箭頭,它代表這個控制器是當前 SB 檔案的入口,會在後面詳細的講解。


2.3 新增控制元件

iOS Storyboard入門及一些高階使用

直接從控制元件區域拖拽了一個 UIView 控制元件到控制器上,然後在 Attributes inspector區域 (點選配置區域中那個楔子形狀的按鈕)直接配置背景顏色為灰色。如果顯示選單欄中沒有沒有你想要的顏色,點選 other ,裡面有多種方式配置顏色,如 RGB 和16進位制顏色等等。

上圖這個區域裡還有一些其他的屬性可以配置,例如 UILabel 控制元件字型和字型顏色等等屬性等,就不深入去展開了。

讀者肯定注意到,控制元件在拖拽中,控制器出現了輔助虛線,可以提醒你相對其他檢視的位置資訊,圖中所示的其中一條就是父檢視的中線。


2.4 佈局控制元件

iOS Storyboard入門及一些高階使用

解釋一下上圖的自動佈局操作:

  • 1.選中控制元件, 點選 Align 按鈕,勾選 Horizontalliy in ContainerVertically in Container,然後新增這兩個佈局,相對於父檢視水平和垂直居中
  • 2.然後點選 Add New Constraints按鈕,新增 WidthHeight 約束,都為200。

到這裡佈局就完成了,因為大小和位置都已經確定。觀察上圖,我只新增了 Align 約束時,介面出現了紅線,這代表約束不完整。並且選單欄上方出現帶有箭頭的小紅點,可以點選進去檢視還有哪些約束沒有完成。這裡還有其他的約束選項,讀者可以自行嘗試。

  • 3、圖中最後,我在 Size inspector 區域 (點選配置區域中那個小直尺按鈕) 雙擊寬度約束,進入了詳情配置介面,這裡可以對約束進行二次修改。點選選單欄的約束,同樣可以進入這個介面。

這裡還有另一種方式進行自動佈局,如圖所示:

iOS Storyboard入門及一些高階使用

按住 Ctrl,然後選中灰色 View ,移動滑鼠會出現一條線,拖到你想要相對其佈局的控制元件,圖中選擇的是父檢視,出現了一個選單讓你選擇約束條件。同樣的操作也能直接在選單欄中進行。甚至當控制器上控制元件比較多不容易選中時,可以直接從控制器上拖到選單欄上的控制元件上。

這一部分的操作是很簡單的,不過需要自動佈局的相關知識。

2.5 開始一個TableView介面

選中選單欄的 View Controller Scene,然後點選鍵盤上的 delete 鍵,刪除我們鼓搗的控制器。

從控制元件區域拖拽一個 UITabBarController 到工作展示區域:

在工作展示空白區域,雙擊滑鼠左鍵和單點滑鼠右鍵,可以放大,縮小顯示內容。

iOS Storyboard入門及一些高階使用

如圖,UITabBarController (它和 UINavigationController 都是容器控制器) 會自帶兩個子控制器,並且有兩個箭頭從 TabBarController 指向它們,這個箭頭的術語叫做 Segue, 這裡的是 Relationship Segue ,代表控制器之間的關係。

刪掉 item1 的控制器,拖拽一個 UITableViewController 出來,然後讓它成為 UINavigationController 的子控制器, 再讓 UINavigationController 成為 UITabBarController 控制器的子控制器,操作如圖所示:

iOS Storyboard入門及一些高階使用

當然你也可以直接拖拽一個 UINavigationController 出來,然後按住 Control 拖動選擇 view controllers。不過我覺得點選 Editor 這種方式更加便捷。

讓我們的關注點來到 UITableViewController ,看到介面上有一個 Prototype Cells ,可以理解為我們平時使用的那種 Cell , 與之對應的是 Static Cells, 從名字就可以看出來,這種是靜態的,不能夠迴圈使用,並且只能在UITableViewController 上使用。

iOS Storyboard入門及一些高階使用

紅框中,和我們程式碼實現中官方提供的4種 Cell 一樣,不過這裡我們需要自定義,下面是完成後的樣子。

iOS Storyboard入門及一些高階使用

可能對沒有接觸過 IB 的讀者來說,這裡還是比較麻煩,所以詳細描述一下。

選中 Cell 在右上角 Size inspector 區域修改 Cell 的高度為120,這裡的高度設定只是方便我們進行佈局,並不是實際顯示的高度。

iOS Storyboard入門及一些高階使用

拖動一個 UIImageView 控制元件到 Cell 裡面,進行佈局。

iOS8 以後更新了讓 Cell 自己自適應高度的新特性,所以這裡我們不光要確定自己的位置和大小,還需要將自己的大小反饋給 Cell 讓其自適應高度,後面詳細使用。

相對於父檢視:

距離右邊20,距離上邊10,寬高100,這就已經確定了位置和大小,不過為了讓 Cell 知道我們的高度,還需要設定一個距離底部的距離。這樣 Cell 就知道顯示的時候需要的高度。結合我們目標的樣子,底部距離的設定是有個小問題的,後面來糾正。

iOS Storyboard入門及一些高階使用

iOS Storyboard入門及一些高階使用

繼續拖動一個 UILableCell 裡。

相對於父檢視: 距離左邊15,上邊10

相對於 UIImageView : 距離它的左邊10

iOS Storyboard入門及一些高階使用

iOS Storyboard入門及一些高階使用

然後比較麻煩的地方來了。再拖動一個 UILableCell 裡。

相對於父檢視: 距離左邊15,距離底部10。

相對於 Game Name Label:距離其底部10。

相對於 UIImageView : 距離它的左邊10。

按照邏輯來說沒問題呀,因為上下左右都給了約束,是什麼原因呢?

iOS Storyboard入門及一些高階使用
iOS Storyboard入門及一些高階使用

我們點選紅框中的小紅點進行檢視:

iOS Storyboard入門及一些高階使用

UILabelUIButton等控制元件有一個特點,它會根據內容自適應自己的大小。

如圖所示兩個 Label 在反饋大小給 Cell 時,Cell 也同樣會反饋自己的大小給兩個 Label,這就會產生兩個問題:

  • 1.如果 Cell 高度比內容反饋需要的高度大的時候,需要拉伸哪個部分的內容?

  • 2.如果 Cell 高度比內容反饋需要的高度小的時候,需要壓縮哪個部分內容?

iOS Storyboard入門及一些高階使用

這裡就需要談到 AutoLayout 中的 Content HuggingContent Compression Resistance

  • 1.Content Hugging Priority: 對應上面的第1中情況,這個屬性的值越高,就越不容易被拉伸。
  • 2.Content Compression Resistance:對應上面的第2種情況,這個屬性的值越高,就越不容易被壓縮。

顯然上面報錯的原因是 Cell 的高度比兩個 Label 的內容高度大了,屬於第一種情況,我們讓 Game Name Label 不拉伸, 增加它的 Content Hugging Priority (預設值為251)比另一個 Label大(增加到252)。

iOS Storyboard入門及一些高階使用

這個問題解決了,但新問題又出現了:

iOS Storyboard入門及一些高階使用

因為 Game Detail Label 被拉伸,導致了內容居中,這看上去怪怪的,以前看到有關於討論讓 Label 居上的問題。但這並不是這裡的解決辦法。還記得前面說過可以對約束進行二次編輯嗎?選中 Game Detail LabelBottom 約束,可以在選單區域選擇或者在小直尺圖示區域裡面找到它進行雙擊,就來到如下介面:

iOS Storyboard入門及一些高階使用

這裡有個 Relation 選項,點看可以看到:

iOS Storyboard入門及一些高階使用

沒錯我們選擇讓這個約束大於或等於10:

iOS Storyboard入門及一些高階使用

看上去是完成了,回到最初新增 UIImageView 約束的時候,我說過有一個小問題,UIImageView 的約束強行的讓 Cell 的高度為120了。當 Label 內容很多換行超過120的時候,就會出現上面的第2種情況, Cell 高度不夠完整顯示內容,這顯然不是我們想要的結果。所以修改 UIImageViewBottom約束也為距離底部大於等於10,到這裡佈局就結束了,最後別忘了設定 identifier :

iOS Storyboard入門及一些高階使用

為了讓 SB 和程式碼關聯起來,建立一個繼承自 UITableControllerGameVC.swift 檔案、繼承自 UITableViewCellGameCell.swift 檔案和資料模型 Game.swift 檔案,然後依次選中 SB 中的檔案關聯:

iOS Storyboard入門及一些高階使用

iOS Storyboard入門及一些高階使用

繼續將 SB 中的屬性和程式碼關聯起來:

iOS Storyboard入門及一些高階使用

也可以直接從控制器中選中控制元件並按住 Control 進行拖動連線,這裡就不再舉例了,這裡不僅僅只能屬性連線,例如 UIButton 可以直接連線一個點選響應方法等等。連線後可以在 Connections inspectors (圓圈包含一個箭頭的按鈕) 檢視:

iOS Storyboard入門及一些高階使用

注意: 一個控制元件屬性關聯多次或者其他關聯錯誤會引發執行奔潰,這是新手最容易犯的問題,如果名字寫錯了,需要先取消上次的關聯,再重新關聯。

iOS Storyboard入門及一些高階使用

Game.swift檔案中:

struct Game {
    let name: String
    let detail: String
    let pictureName: String
    
    static func getData() -> [Game] {
        return [
        Game(name: "絕地求生",
        detail: "神仙打架遊戲",
        pictureName: "game_one"),
        Game(name: "英雄聯盟",
        detail: "《英雄聯盟》(簡稱LOL)是由美國拳頭遊戲(Riot Games)開發、中國大陸地區騰訊遊戲代理運營的英雄對戰MOBA競技網遊。遊戲裡擁有數百個個性英雄,並擁有排位系統、符文系統等特色養成系統。《英雄聯盟》還致力於推動全球電子競技的發展,除了聯動各賽區發展職業聯賽、打造電競體系之外,每年還會舉辦“季中冠軍賽”“全球總決賽”“All Star全明星賽”三大世界級賽事,獲得了億萬玩家的喜愛,形成了自己獨有的電子競技文化",
        pictureName: "game_two")]
    }
}
複製程式碼

GameVC.swift 檔案中:

class GameVC: UITableViewController {
    var games: [Game] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        games = Game.getData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return games.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "GameCell", for: indexPath) as! GameCell
        cell.game = games[indexPath.row]
        return cell
    }
}
複製程式碼

GameCell.swift 檔案中:

class GameCell: UITableViewCell {
    var game: Game! {
        didSet {
            gameNameLabel.text = game.name
            gameDetailLabel.text = game.detail
            gameImageView.image = UIImage(named: game.pictureName)
        }
    }
    
    @IBOutlet weak var gameImageView: UIImageView!
    @IBOutlet weak var gameNameLabel: UILabel!
    @IBOutlet weak var gameDetailLabel: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
}
複製程式碼

準備工作完畢,執行 Demo:

iOS Storyboard入門及一些高階使用

出錯了,細心的讀者肯定早就發現這個問題了,那就是前面說的那個入口箭頭:

iOS Storyboard入門及一些高階使用

配置完畢後再執行:

iOS Storyboard入門及一些高階使用

2.6 介面之間跳轉

先給控制器增加一個 title:

iOS Storyboard入門及一些高階使用

然後把 Game 控制器拖到 UITabBarController 第一個位置:

iOS Storyboard入門及一些高階使用

繼續新增一個 UIBarButtonItem, 並設定風格為 Add

iOS Storyboard入門及一些高階使用

新增一個 UITableViewController 並讓其成為 UINavigationController的子控制器 ,按住Control 點選 Add Item ,拖動到新的控制器上,會出現彈窗選擇跳轉方式,這裡選擇 Present Modally ,對應著我們程式碼中 Present 那個方法。

這裡的 Show 代表,如果是 UINavigationController 的子控制器就會執行 Push 方法,不是就會執行 Present 方法。

iOS Storyboard入門及一些高階使用

兩個控制器之間多出了一個帶箭頭的連線,這可以理解為介面切換 Segue ,用來描述控制器之間的跳轉,一個介面切換 Segue 只能單向跳轉。

設定新控制器的 titleGame Add ,左邊新增一個 Cancle Item, 右邊新增一個 Done Item 。然後繼續在 GameVC.Swift 的底部新增分類。

// MARK: - IBActions
extension GameVC {
    @IBAction func cancelToGameVC(_ segue: UIStoryboardSegue) {
        
    }
    @IBAction func saveGameDetail(_ segue: UIStoryboardSegue) {
        
    }
}
複製程式碼

這是 unwind Segue,用來返回到目標控制器。直接上圖:

iOS Storyboard入門及一些高階使用

選中 Game Add 中的 TableView.接下來我直接用 static cell 進行佈局,

  • 1.content 中選擇 Static CellsStyle 中選擇 Grouped
  • 2.將出現的 Section 中的 Cell 刪除到只剩一個,設定 CellSelectionNone, 直接複製 Section,這樣就有兩個含有一個 CellSection
  • 3.給 Section 設定標題( SB 中的 Header )為 Game NameGame Detail
  • 4.將第一個 Section 高度設為50,第二個設為200。拖一個 UITextField 到第一個 Cell ,佈局上0底0左10右10,拖一個 UITextView 到第二個 Cell,佈局上底左右都是10。
  • 5.建立繼承於 UITableViewControllerGameAddVC.swift 檔案,然後將裡面方法刪除到只剩 viewDidLoad , 並關聯這個 SB
  • 6.將步驟3中的 UITextFieldUITextView 連線到 GameAddVC.swift檔案中生成 @IBOutlet 屬性。
@IBOutlet weak var gameNameTextField: UITextField!
@IBOutlet weak var gameDetailTextView: UITextView!
複製程式碼

這裡之所以能直接將 Cell 中的屬性直接連線到控制器中,是因為靜態 Cell 不會重用。

配置完成如下:

iOS Storyboard入門及一些高階使用

這裡省略了新增圖片的步驟,直接設定一個預設圖片。

  • 選中剛才 Done Item 新增的 Segue,然後設定它的 IdentifierAddGameDetail

    iOS Storyboard入門及一些高階使用

  • AddGameVC.swift 中重寫父類方法並新增程式碼:

var game: Game?

// 這個方法點選 `Done` 的時候會呼叫
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "GameAddDetail",
    let name = gameNameTextField.text {
        game = Game(name: name,
             detail: gameDetailTextView.text!,
             pictureName: "game_default")
    }
}
複製程式碼
  • GameVC.swift 中,新增如下程式碼:
// 這個方法前面有,只是新增方法內的內容
@IBAction func saveGameDetail(_ segue: UIStoryboardSegue) {
    guard let gameAddVC = segue.source as? GameAddVC,
        let game = gameAddVC.game else {
            return
    }
  
    games.append(game)
    let indexPath = IndexPath(row: games.count - 1, section: 0)
    tableView.insertRows(at: [indexPath], with: .automatic)
}
複製程式碼

執行 Demo, 如下:

iOS Storyboard入門及一些高階使用

2.7 Storyboard Reference

SB中,如果多個人同時對一個地方(例如同一個控制器)進行修改,很容易造成 Git 衝突,這也是反對者們反對使用 SB 的一個理由。不過在蘋果增加 Storyboard Reference 功能後,這種情況在開發中完全可以避免了。

iOS Storyboard入門及一些高階使用

Demo 中的控制器數量較少,但在實際專案中,如果多個人都都只操作這個 Main.storyboard ,那將是一件很恐怖的事情。之前沒有 Storyboard Reference 功能時,多個 SB 之間的跳轉只能使用程式碼的方式實現。現在來看看 Storyboard Reference 吧。

  • 1.按住滑鼠左鍵,然後圈中你想要脫離 Main.storyboard 的控制器,就像桌面用滑鼠多選檔案那樣。
  • 2.點選 Editor>Refactor to Storyboard。
  • 3.取名為 Game.storyboard,選擇在哪個資料夾下面建立,然後確定。

iOS Storyboard入門及一些高階使用

完成後,我們可以看到 Main.storyboard 中的控制器變成了一個了 Storyboard Reference,其他控制器移到我們新建立的 Game.storyboard 中去了。多人開發時,各自操作自己的業務 SB ,就基本避免了 Git 衝突。

同樣,我們也可以先直接建立 SB 檔案,然後再從控制元件區拖拽一個 Storyboard Reference, 然後再讓它和我們新建立的 SB 檔案關聯。

iOS Storyboard入門及一些高階使用

到這裡這一下節就結束了,我自認為是寫得比較囉嗦,不過這也是沒有辦法的選擇,這部分知識更多的是介面上的操作,如果不寫明白,不容易闡述清楚!

3 Storyboard高階用法

這裡的所謂高階用法,是我一廂情願認為的。

3.1 @IBInspectable

如果你之前沒有見過這個東西,那麼你肯定為某些屬性沒有暴露在 IB 的設定皮膚中而困擾過。@IBInspectable 的用處很簡單,就是讓我們自定義的屬性也能直接在 IB 中選擇,例如貓神的文章中的建議:

  • 為一個顯示文字的 view 設定本地化字串:
extension UILabel {
    @IBInspectable var localizedKey: String? {
        set {
            guard let newValue = newValue else { return }
            text = NSLocalizedString(newValue, comment: "")
        }
        get { return text }
    }
}

extension UIButton {
    @IBInspectable var localizedKey: String? {
        set {
            guard let newValue = newValue else { return }
            setTitle(NSLocalizedString(newValue, comment: ""), for: .normal)
        }
        get { return titleLabel?.text }
    }
}

extension UITextField {
    @IBInspectable var localizedKey: String? {
        set {
            guard let newValue = newValue else { return }
            placeholder = NSLocalizedString(newValue, comment: "")
        }
        get { return placeholder }
    }
}
複製程式碼

IB 中可以直接設定:

iOS Storyboard入門及一些高階使用

  • 為一個 image view 設定圓角(這裡可以直接擴充套件 UIView
@IBInspectable var cornerRadius: CGFloat {
   get {
       return layer.cornerRadius
   }
   
   set {
       layer.cornerRadius = newValue
       layer.masksToBounds = newValue > 0
   }
}
複製程式碼

IB 中可以直接設定:

iOS Storyboard入門及一些高階使用

僅僅使用 @IBInspectable 無法將屬性的設定實時顯示出來,還需要另一個關鍵字的幫助。

3.2 @IBDesignable

它能夠將一些繪圖程式碼和 UIView 及其子類的 @IBInspectable 屬性實時渲染到 IB 中。

  • 1.結合 @IBInspectable 使用,建立 UIView 子類 CustomView。拖拽一個 UIView 到另一個 Item 控制器上,佈局上下居中,款高200,然後將它們關聯。此時如圖所示:

iOS Storyboard入門及一些高階使用

  • 2.在 CustomView.swift 中新增程式碼,注意 @IBDesignable 的位置:
@IBDesignable
class CustomView: UIView {

    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }

    @IBInspectable var borderColor: UIColor = UIColor.white {
        didSet {
            layer.borderColor = borderColor.cgColor
        }
    }

    @IBInspectable var borderWidth: Int = 1 {
        didSet {
            layer.borderWidth = CGFloat(borderWidth)
        }
    }

}
複製程式碼

然後看效果:

iOS Storyboard入門及一些高階使用

  • 3.再新增繪圖程式碼,並將上面的 Corner Radius 設為0:
override func draw(_ rect: CGRect) {
    let path = UIBezierPath(ovalIn: rect)
    UIColor.green.setFill()
    path.fill()
}
複製程式碼

結果如圖:

iOS Storyboard入門及一些高階使用

3.3 自定義Segue跳轉動畫

我們都知道 Presnet 切換時系統預設的公開動畫有四種,如果我們想自定義的話,需要建立一個 UIStoryboardSegue 的子類。

iOS Storyboard入門及一些高階使用

class CustomAnimationPresentationSegue: UIStoryboardSegue, , UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning {

    override func perform() {
        destination.transitioningDelegate = self
        super.perform()
    }
    
    func animationController(forPresented presented: UIViewController, 
    presenting: UIViewController,
    source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }
    
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }
    
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerView = transitionContext.containerView
        
        let toView = transitionContext.view(forKey: UITransitionContextViewKey.to)!
        
        if transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) == destination {
            // Presenting.
            UIView.performWithoutAnimation {
                toView.alpha = 0
                containerView.addSubview(toView)
            }
            
            let transitionContextDuration = transitionDuration(using: transitionContext)
            
            UIView.animate(withDuration: transitionContextDuration, animations: {
                toView.alpha = 1
            }, completion: { success in
                transitionContext.completeTransition(success)
            })
        }
        else {
            // Dismissing.
            let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from)!
            
            UIView.performWithoutAnimation {
                containerView.insertSubview(toView, belowSubview: fromView)
            }
            
            let transitionContextDuration = transitionDuration(using: transitionContext)
            
            UIView.animate(withDuration: transitionContextDuration, animations: {
                fromView.alpha = 0
            }, completion: { success in
                transitionContext.completeTransition(success)
            })
        }
    }
    
}
複製程式碼

自定義了一個簡單的漸隱動畫,這裡關於自定義的跳轉動畫的部分我不想仔細探討(排在我想寫內容的佇列總)。然後我們在 IB 關聯跳轉到新增遊戲的 SegueCancle&Doneunwind SegueCustomAnimationPresentationSegue。 演示效果:

iOS Storyboard入門及一些高階使用

3.4 使用R.swift三方框架

R.swift Github地址

其實這不算是 IB 的高階使用,它能夠掃描整個專案中的資原始檔(比如圖片名,View Controllersegueidentifier 等),並生成一種型別安全的獲取方式。

let icon = UIImage(named: "settings-icon")
let viewController = UIStoryboard(name: "Main",
bundle: nil).instantiateViewController(withIdentifier: "myViewController") as! MyViewController
複製程式碼
let icon = R.image.settingsIcon()
let viewController = R.storyboard.main.myViewController()
複製程式碼

四、後記及Demo

Demo Github地址

關於 IB 的操作目前我知道的就這些,如果你有更好的使用技巧可以評論分享討論一下。

最近我撿起了我的微博,因為很多 iOS 界的前輩都喜歡微博分享技術,我也關注了很多,收益匪淺。例如這個 OC 專案 ZHNCosmos Github地址,程式碼工整,邏輯清晰,我這個菜鳥準備好好學習一下。

另外附上我的微博,我每天都會轉發一些大佬的技術動態,請大家隨緣關注:

我的微博地址

參考文章

貓神部落格 再看關於 Storyboard 的一些爭論

WWDC2015視訊自帶中文字幕 What's New in Storyboards

英文 Storyboards Tutorial for iOS: Part 1

英文 Storyboards Tutorial for iOS: Part 2

相關文章