從單一畫面的 Hello World 進階到多畫面導航,是 iOS 開發的必經之路。本文以 MonoTouch (現 Xamarin.iOS) 為例,詳細講解 Cocoa Touch 版 MVC 架構、View/View Controller 分工、UINavigationController 導航堆疊機制,並完整示範如何用 Interface Builder 與 C# 代碼協作構建可擴展的多畫面應用。
傳統 MVC 將 Model(資料)、View(呈現)、Controller(邏輯)三層分離。Cocoa Touch 採用 View + View Controller 合體模式:
這種設計讓 View 可複用(同一 View 可由不同 Controller 驅動),Controller 專注流程控制,符合單一職責原則。
UINavigationController 維護一個 View Controller 堆疊,提供:
PushViewController:將新 VC 推入堆疊,顯示新畫面PopViewController:彈出頂層 VC,返回上一畫面在 MonoDevelop 建立 MonoTouch iPhone Solution,新增兩個 UIViewController 子類別:HelloWorldScreen、HelloUniverseScreen,各自對應 .xib 佈局一個 Label。
MainWindow.xib 拖入 UINavigationController,其內含 Navigation Bar、根 View Controller。UITableView 作為選單,設定 Outlet:mainNavigationController、mainNavTableView。封裝選單項目資訊,支援 Controller 延遲實例化:
public class NavItem {
public string Name { get; set; } // 顯示文字
public UIViewController Controller { get; set; } // 已實例化的 VC
public Type ControllerType { get; set; } // VC 類型(延遲建立用)
public object[] ControllerConstructorArgs { get; set; } // 建構參數
}
繼承 UITableViewDataSource,實作 RowsInSection、GetCell。利用 DequeueReusableCell 重用 Cell 提升效能:
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) {
const string cellId = "SimpleCellTemplate";
var cell = tableView.DequeueReusableCell(cellId)
?? new UITableViewCell(UITableViewCellStyle.Default, cellId);
cell.TextLabel.Text = _navItems[indexPath.Row].Name;
cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
return cell;
}
繼承 UITableViewDelegate,在 RowSelected 中根據 NavItem 推入對應 VC:
public override void RowSelected(UITableView tableView, NSIndexPath indexPath) {
var item = _navItems[indexPath.Row];
UIViewController vc = item.Controller
?? Activator.CreateInstance(item.ControllerType, item.ControllerConstructorArgs) as UIViewController;
if (vc != null) {
item.Controller = vc; // 快取避免重複建立
_navigationController.PushViewController(vc, true);
_navigationController.NavigationBarHidden = false;
}
tableView.DeselectRow(indexPath, true);
}
public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
window.AddSubview(mainNavigationController.View);
window.MakeKeyAndVisible();
_navItems = new List {
new NavItem("Hello World", typeof(HelloWorldScreen)),
new NavItem("Hello Universe", typeof(HelloUniverseScreen))
};
mainNavTableView.DataSource = new NavTableViewDataSource(_navItems);
mainNavTableView.Delegate = new NavTableDelegate(mainNavigationController, _navItems);
return true;
}
MainWindow.xib 載入時找不到對應屬性。DidReceiveMemoryWarning 釋放可重建的 Controller 快取。Storyboard + Segue 視覺化設計導航流程(iOS 5+)。MVVM + ReactiveUI 實現 ViewModel 驅動導航,提升可測試性。Xamarin.Forms 跨平台共用導航邏輯。掌握 UINavigationController 與 MVC 分層,即可構建結構清晰、易於維護的 iOS 應用骨架。下一步嘗試加入 Tab Bar Controller、Modal Presentation、Unwind Segue 等進階導航模式,豐富互動體驗。