沒有故事板的世界
我們的第一步當然是直接將故事板刪除,點擊左方檔案總管中的Main.storyboard
並按下delete
,此時試著按Run
在模擬器上運行程式看看,你將會發現專案無法順利執行了!
這是因為在系統預設的專案設定中,會去自動尋找Main.storyboard
,而在找不到檔案的時候只能報錯。點擊左方檔案總管最上端的、圖標有個藍色 A 的HelloWorld
,這是我們的專案檔案,在正中間的視窗選擇TARGETS
中的HelloWorld
,找到Deployment Info
這個區塊,會看到Main Interface
選項中,目前的設定還是Main.storyboard
,我們將它清除為空白。
現在,程式可以運行了,但執行時將會看到一片漆黑,這是因為現在Storyboard Entry Point
、視圖和與視圖有關的連結都被移除了,因此系統既沒有任何視圖,也不知道啟動時要做什麼,由於啟動是一項APP
層級的事件,我們將會把這個任務委託給AppDelegate.swift
處理。
打開這個檔案,在class AppDelegate
的第一行,我們看到了這個類別中唯一的屬性:
var window: UIWindow?
UIWindow
是一種特殊的視圖,通常整個專案的生命中只會有一個,它掌管所有視圖顯示任務的大主管,在使用故事板時,初始化這個變數的任務被系統自動完成了,而在我們刪除了故事板後,這個變數因為加了代表Optional
的?
,因此它被自動初始化為nil
,也就是沒有值。現在,初始化的任務被交到我們手上了。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) let firstViewController = ViewController() window!.rootViewController = firstViewController window!.makeKeyAndVisible() return true }
application
是程式成功啟動後會呼叫AppDelegate
執行的第一個任務,因此我們將初始化window
變數、綁定第一個視圖的任務都撰寫在這個func
中,每行程式碼的意義分別解釋如下:
window = UIWindow(frame: UIScreen.main.bounds)
將window
初始化,其尺寸等於UIScreen.main.bounds
,這個值就是螢幕的尺寸。
let firstViewController = ViewController() window!.rootViewController = firstViewController
宣告一個名為firstViewController
的常數,並以ViewController()
初始化它,隨後將window
的rootViewController
屬性設為這個常數,其意義和Storyboard Entry Point
相同,即是指這個window
物件進入時綁定的第一個視圖控制器。
window!.makeKeyAndVisible()
最後,執行window
物件的makeKeyAndVisible()
指令,此指令會在程式中讓window
被真正的顯示出來。
運行程式,將會再次看到一片漆黑的視圖,這是因為我們還沒設定視圖的背景顏色,但我們可以在ViewController.swift
中的func viewDidLoad()
指令裡加入print("init")
之類的列印指令來測試一下視圖是否真的有載入,在每次視圖載入完畢時,它的控制器物件中的viewDidLoad()
都會被執行一次。
可以看到在 Xcode 正下方偏右的視窗中,init
訊息被列印了出來,這個區域稱為「除錯區」,會顯示所有被print
指令列印的訊息,或者重要的系統訊息,在測試一些想法時非常重要。在我們現在的測試裡,它告訴了我們:視圖確確實實被載入了。
接著我們除了要處理背景顏色的設計以外,還需要把按鈕加入進來,現在按鈕和它的事件都不會經過 Interface Builder 了,因此我們可以把@IBOutlet
、@IBAction
標籤都拿掉,並且還需要手動撰寫設置各種按鈕屬性的程式碼...
class ViewController: UIViewController { var helloButton: UIButton? override func viewDidLoad() { super.viewDidLoad() // 設置視圖背景顏色為白色 self.view.backgroundColor = UIColor.white // 設置按鈕位置和大小 helloButton = UIButton(frame: CGRect(x: 50, y: 50, width: 200, height: 50)) // 設置按鈕背景為藍色 helloButton!.backgroundColor = UIColor.blue // 設置按鈕標題 helloButton!.setTitle("Hello World!", for: UIControlState.normal) // 增加按鈕事件,連結至 helloWorld(sender:) helloButton!.addTarget(self, action: #selector(helloWorld(sender:)), for: UIControlEvents.touchUpInside) // 將按鈕加入視圖(self.view)中 self.view.addSubview(helloButton) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func helloWorld(sender: UIButton) { // 按下時,將按鈕的背景顏色改為紅色 sender.backgroundColor = UIColor.red } }
運行!這下和原先的 Hello World! 效果一模一樣了!