蘋果開發中什么是Storyboard?object-c 和swiftui 以及Storyboard到底有什么關系以及邏輯?優雅草卓伊凡
引言
由于最近有個客戶咨詢關于 蘋果內購 in-purchase 的問題做了付費咨詢處理,得到問題:“昨天試著把您的那幾部分code 組裝成一個 project, 并運行了一下,出現了不少問題。總結如下,請您指教了。”
- 我原來的項目都是用 single storyboard 的模版做的,沒有像現在這樣組裝過 project,所以首先不知組裝的project 是否正確。我把 弄好的 project 附在后面了,請您幫助看下,看運行的情況是否正常。
這里我們需要知道 什么是single storyboard
好的,我們來詳細解釋一下 “single storyboard” 這個概念。
在軟件開發,特別是 iOS 應用開發 的上下文中,“single storyboard” 指的是一種使用 單個 Storyboard(故事板)文件 來設計和管理整個應用程序所有用戶界面(UI)和界面之間導航流程的架構方法。
這與使用 多個 storyboard 或將 storyboard 與純代碼創建界面相結合 的方法形成對比。
1. 什么是 Storyboard?
首先,快速回顧一下 Storyboard 是什么:
- 可視化工具:Storyboard 是 Xcode 集成開發環境中的一個可視化畫布。
- 表示屏幕(ViewController):你可以在上面拖放各種UI組件(如按鈕、標簽、表格)來構建一個個的視圖控制器(View Controller)。
- 表示流程(Segue):它還能展示不同屏幕之間的轉換關系(通過 Segue 連接),讓你清晰地看到整個App的用戶流。
2. Single Storyboard 的特點
- 一個文件管理所有:整個應用程序的每一個界面(例如:登錄頁、主頁、設置頁、詳情頁)都集中在同一個
.storyboard
文件中。 - 直觀的整體流程:開發者可以一眼看遍所有界面以及它們是如何跳轉的,對于小型項目來說,這非常易于理解和上手。
- Apple 早期的默認模板:在 Xcode 的早期版本中,創建新項目時默認就是使用 single storyboard(比如
Main.storyboard
),這使其成為許多初學者的入門選擇。
3. 優點
- 簡單直觀:對于頁面數量不多的小型應用來說,管理和查看所有界面非常方便。無需在多個文件之間切換。
- 易于學習:非常適合初學者,可以快速通過拖拽搭建出完整的App原型,理解界面間的導航邏輯。
- 可視化導航:所有頁面流(Segues)都在一個文件里清晰可見,降低了理解代碼中導航邏輯的復雜度。
- 快速原型開發:在項目初期或制作演示原型時,可以極快地構建出完整的用戶流程。
4. 缺點(也是為什么現在不常被推薦用于大型項目的原因)
- 嚴重的協作沖突:這是最大的問題。因為所有界面都在一個文件里,當多個開發者同時修改這個 storyboard 時,極易發生 git 合并沖突。這個沖突文件是XML格式,幾乎無法手動解決,通常需要靠隊友回退修改,非常耗時。
- 性能問題:當一個 storyboard 包含大量視圖控制器時,Xcode 打開、編輯和渲染它的速度會變得非常慢,影響開發效率。
- 難以模塊化/組件化:無法按功能模塊將界面分離,所有東西都耦合在一起。如果想重用某個功能的界面集,會非常困難。
- 責任不清晰:在大型團隊中,很難界定哪個開發者負責哪一部分的界面,因為大家都工作在同一個文件上。
5. 現代最佳實踐和替代方案
由于上述缺點,特別是協作問題,現代iOS開發中對于中型及以上項目,通常不再使用 single storyboard。
常見的替代方案包括:
- Multiple Storyboards (多個故事板)
- 將應用按功能模塊拆分成多個 storyboard 文件。例如:
Login.storyboard
,Home.storyboard
,Profile.storyboard
。 - 大大減少了git沖突,不同開發者可以負責不同模塊的storyboard。
- 使用
UIStoryboard(name: "Name", bundle: nil).instantiateViewController(...)
來加載特定故事板中的視圖控制器。
- 將應用按功能模塊拆分成多個 storyboard 文件。例如:
- Storyboard + XIB 組合
- 使用一個主 storyboard 作為基礎,同時結合一些XIB文件來創建獨立的、可重用的視圖或視圖控制器。
- 純代碼布局(Programmatic UI)
- 完全不使用 Storyboard 或 XIB,所有界面都用代碼(如 Swift 或 Objective-C)來創建和約束(常用 SnapKit 或原生 NSLayoutConstraint)。
- 優點:完全避免任何界面文件的沖突;精確的版本控制(diff清晰);可讀性強;易于實現復雜的動態布局。
- 這是目前很多大型公司和團隊推崇的方式,但學習曲線相對較陡。
- SwiftUI
- Apple 推出的新一代聲明式UI框架。它完全摒棄了 Storyboard 和 Interface Builder。
- 界面用 Swift 代碼聲明,預覽畫布會實時更新。它天生就解決了 Storyboard 的協作和性能問題,是Apple未來的發展方向。
總結
Single Storyboard 是一種將所有界面集中在一個故事板文件中的UI構建方法。它簡單易學,適合初學者和小型個人項目。但由于其致命的協作沖突和性能問題,在專業的、多人協作的中大型項目中已被視為一種反模式(Anti-Pattern)。
現代iOS開發更傾向于使用 Multiple Storyboards、純代碼 或 SwiftUI 來構建應用程序。
好的,這是一個非常好的問題,因為它觸及了iOS開發中兩個完全不同維度的概念。將它們進行對比,能幫助你更深刻地理解iOS開發的架構和演變。
“Single Storyboard” 和 “Objective-C語言開發” 之間的區別,本質上是 “UI構建方法” 與 “編程語言” 的區別。它們不是一個層面的東西,因此不能直接比較孰優孰劣,而是需要理解它們如何協同工作。
我們可以用一個簡單的比喻來開場:
- Objective-C 就像是 建筑材料(如水泥、鋼筋、磚頭),決定了建筑的結構和強度。
- Storyboard 就像是 建筑圖紙和室內設計圖,決定了建筑的外觀、布局和房間之間的連接。
你可以用 同一種材料(Objective-C 或 Swift),按照 不同的圖紙(Single Storyboard, Multiple Storyboards, 純代碼)來建造房子。
概念維度對比
特性維度 | Single Storyboard | Objective-C |
本質 | UI設計和布局工具, 一個XML文件 | 編程語言 |
范疇 | “如何做UI” - 是架構和工具鏈的選擇 | “用什么寫代碼” - 是語言的選擇 |
關系 | 是一種可用工具,可以用Objective-C或Swift來配合它操作 | 是一種實現語言,可以用來編寫操作Storyboard的邏輯,也可以不用Storyboard |
功能 | 可視化地創建視圖控制器(ViewController)、UI元素(按鈕、標簽等)和界面之間的跳轉邏輯(Segue) | 實現應用程序的業務邏輯、數據模型、網絡請求、數據庫操作、性能優化等所有功能 |
輸出物 | 生成一個 文件,本質是XML | 生成 和 源代碼文件 |
可替代性 | 可被 Multiple Storyboards、XIBs、純代碼布局、SwiftUI 替代 | 可被 Swift 語言替代 |
詳細闡述
1. Single Storyboard:一種UI構建策略
Single Storyboard強調的是 “用一個文件管理所有界面”。
- 如何與Objective-C配合?
- 你在
Main.storyboard
上拖拽一個ViewController和一個Button。 - 你需要創建一個
MyViewController.h
/MyViewController.m
文件,并將storyboard中的ViewController的Class設置為MyViewController
。 - 你可以在
.m
文件中用Objective-C語法為那個Button創建 IBAction 出口(Action)。 - 當按鈕被點擊時,storyboard中的可視化Segue可能會觸發跳轉,但跳轉前后的數據準備和傳遞工作(例如
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
)仍然需要你用Objective-C(或Swift)來編寫。
- 你在
// MyViewController.m
#import "MyViewController.h"
#import "DetailViewController.h" @implementation MyViewController// 1. 這是一個通過IBAction關聯到Storyboard中按鈕點擊事件的方法
- (IBAction)buttonTapped:(id)sender {NSLog(@"Button tapped! This is Objective-C code.");
}// 2. 這是在執行Storyboard中的Segue跳轉前,傳遞數據的方法
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {if ([segue.identifier isEqualToString:@"showDetail"]) {DetailViewController *detailVC = segue.destinationViewController;detailVC.data = @{@"key": @"value"}; // 用Objective-C準備數據}
}@end
核心思想:Storyboard負責“看得到”的部分和簡單的流程,Objective-C代碼負責“看不見”的邏輯和復雜操作。
2. Objective-C:一種編程語言
Objective-C是一種通用、面向對象的編程語言。它完全不關心你的UI是怎么做出來的。
- 它可以與任何UI構建方式配合:
- 配合 Single Storyboard: 如上所述。
- 配合 Multiple Storyboards: 你用
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Other" bundle:nil];
來加載其他故事板。 - 配合純代碼(Programmatically): 這是最能體現Objective-C能力的方式。你完全不用任何Storyboard或XIB文件。
// AppDelegate.m - 純代碼方式啟動應用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// 1. 創建窗口(完全用Objective-C代碼)self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];self.window.backgroundColor = [UIColor whiteColor];// 2. 創建根視圖控制器MyRootViewController *rootVC = [[MyRootViewController alloc] init];// 3. 創建導航控制器UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootVC];// 4. 設置窗口的根視圖控制器self.window.rootViewController = navController;// 5. 顯示窗口[self.window makeKeyAndVisible];return YES;
}// MyRootViewController.m - 純代碼方式構建界面
- (void)viewDidLoad {[super viewDidLoad];// 1. 創建按鈕(完全用Objective-C代碼)UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];button.frame = CGRectMake(100, 100, 200, 50);[button setTitle:@"Press Me" forState:UIControlStateNormal];[button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:button];// ... 可以使用類似Masonry的庫來代碼設置AutoLayout約束 ...
}- (void)buttonTapped:(id)sender {// 2. 用Objective-C代碼實現跳轉邏輯DetailViewController *detailVC = [[DetailViewController alloc] init];detailVC.data = @{@"key": @"value"};[self.navigationController pushViewController:detailVC animated:YES];
}
核心思想:Objective-C是實現的基石,無論UI層面如何選擇,最終的功能都要靠它(或Swift)來實現。
總結與類比
場景 | 解釋 |
使用 Single Storyboard + Objective-C | 這是 iOS 5~8時代非常經典和常見的模式。開發者用Objective-C寫業務邏輯,同時享受Storyboard可視化搭建UI的便利。適合小型項目或初學者。 |
使用 純代碼(Objective-C) | 這是 大型項目、多人協作 的首選。避免了Storyboard的合并沖突,對UI的控制力極強,方便復用和組件化。對開發者要求較高。 |
使用 Single Storyboard + Swift | 和第一種一樣,只是編程語言從Objective-C換成了更現代的Swift。 |
使用 純代碼(Swift) | 目前最主流的高級開發模式之一。結合Swift語言的安全和表達力,以及純代碼的維護優勢。 |
結論:
把它們看作“區別”不如看作“組合”。Objective-C是語言,是基礎;Single Storyboard是工具,是策略。 你可以用Objective-C去操作Single Storyboard,也可以用Objective-C完全拋開Storyboard。
在iOS開發的演進中,我們經歷了:
- Objective-C + Storyboard/XIB (舊時代主流)
- Objective-C + 純代碼 (舊時代大型項目首選)
- Swift + Storyboard/XIB (過渡期)
- Swift + 純代碼 (當前時代主流之一)
- Swift + SwiftUI (Apple推動的未來方向)