1、前言
我們先來看一下這幾個(gè)概念的類繼承關(guān)系圖:
iOS 中,所有顯示在界面上的對(duì)象都是從 UIResponder 直接或間接繼承的。
2、應(yīng)用程序(UIApplication)
一個(gè) UIApplication 對(duì)象就代表一個(gè)應(yīng)用程序。一個(gè) iOS 程序啟動(dòng)后創(chuàng)建的第一個(gè)對(duì)象就是 UIApplication 對(duì)象(只有一個(gè)),而且是單例的。
如有需要,可以通過如下代碼獲取該單例對(duì)象:
1. let app = UIApplication.sharedApplication()
利用 UIApplication 對(duì)象,可以進(jìn)行一些應(yīng)用級(jí)別的操作。
(1)設(shè)置應(yīng)用圖標(biāo)右上角的紅色提醒數(shù)字
app.applicationIconBadgeNumber = 3
(2)設(shè)置聯(lián)網(wǎng)指示器的可見性
app.networkActivityIndicatorVisible = true
(3)管理狀態(tài)欄
app.setStatusBarStyle(UIStatusBarStyle.Default, animated: true)
app.setStatusBarHidden(false, withAnimation: UIStatusBarAnimation.Fade)
(4)openURL 方法
// 發(fā)信息
app.openURL(NSURL(string: "sms://10010")!)
// 發(fā)郵件
app.openURL(NSURL(string: "mailto://jinnchang@126.com")!)
// 打開一個(gè)網(wǎng)頁
app.openURL(NSURL(string: "http://blog.csdn.net/jinnchang")!)
// 跳轉(zhuǎn)到 AppStore
app.openURL(NSURL(string: "https://itunes.apple.com/cn/app/qq/id444934666?mt=8")!)
3、視圖(UIView)
UIView 的實(shí)例即視圖,負(fù)責(zé)在屏幕上定義一個(gè)矩形區(qū)域,同時(shí)處理該區(qū)域的繪制和觸屏事件。視圖可以嵌套,也可以像圖層一樣進(jìn)行疊加。
4、窗口(UIWindow)
UIWindow 管理和協(xié)調(diào)應(yīng)用程序的顯示,雖然 UIWindow 繼承自 UIView,但通常不直接操作 UIWindow 對(duì)象中與視圖相關(guān)的屬性變量。
iOS 程序啟動(dòng)完畢后,創(chuàng)建的第一個(gè)視圖控件就是 UIWindow(創(chuàng)建的第一個(gè)對(duì)象是 UIApplication),接著創(chuàng)建控制器的 view,最后將控制器的 view 添加到 window 上,于是控制器的 view 就顯示在屏幕上了。一般情況下,應(yīng)用程序只有一個(gè) UIWindow 對(duì)象,即使有多個(gè),也只有一個(gè) UIWindow 可以接受到用戶的觸屏事件。
(1)自定義一個(gè) myWindow
let myWindow = UIWindow(frame: UIScreen.mainScreen().bounds)
(2)設(shè)置 myWindow 為主窗口并顯示出來(view 不能憑空顯示,必須依賴 window)
myWindow.makeKeyAndVisible()
UIWindow 和 UIView 之間的關(guān)系也可以想象成這樣一個(gè)場(chǎng)景:首先會(huì)有一個(gè)空的畫框(UIWindow),我們?cè)诋嬁蛏戏胖靡粔K畫布(UIView),然后可以在這個(gè)畫布上進(jìn)行繪畫。畫布上可能會(huì)被畫上各種元素,例如 UILabel、UIButton 等,這些元素其實(shí)也是一個(gè)又一個(gè) UIView,它們會(huì)有一個(gè)層級(jí)關(guān)系管理,有點(diǎn)類似于 Photoshop 中圖層的概念,層級(jí)高的元素會(huì)覆蓋住層級(jí)低的元素,從而導(dǎo)致層級(jí)低的元素被部分或完全遮擋。
5、屏幕(UIScreen)
通過這個(gè)類我們可以獲取一些關(guān)于屏幕的信息,通常用來獲取屏幕尺寸。
// 返回帶有狀態(tài)欄的 Rect
let screenBounds = UIScreen.mainScreen().bounds
// 返回不含狀態(tài)欄的 Rect
let viewBounds = UIScreen.mainScreen().applicationFrame
6、視圖控制器(UIViewController)
視圖控制器管理 UIView 實(shí)例的生命周期及資源的加載與釋放、處理由于設(shè)備旋轉(zhuǎn)導(dǎo)致的界面旋轉(zhuǎn)、以及和用于構(gòu)建復(fù)雜用戶界面的高級(jí)導(dǎo)航對(duì)象進(jìn)行交互。
下圖展示了 UIView、UIWindow、UIScreen、UIViewController 之間的層級(jí)關(guān)系:
想要完整了解 UIViewController 用法可以參考 Github 上關(guān)于 UIViewController 的示例:UIViewControllerSample
7、導(dǎo)航控制器(UINavigationController)
在介紹 UINavigationController 之前先介紹另一個(gè)概念:容器(Container)。一個(gè) app 可能有很多的 UIViewController 組成,這時(shí)需要一個(gè)容器來對(duì)這些 UIViewController 進(jìn)行管理。大部分的容器也是一個(gè) UIViewController,如 UINavigationController、UITabBarController,也有少數(shù)不是 UIViewController,比如 UIPopoverController 等。
UINavigationController 繼承自 UIViewController,通常我們新建的工程是直接將視圖控制器添加到 window 上的,如果添加了 navigation 以后就多了一層。
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
// 初始化 window
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.backgroundColor = UIColor.grayColor()
// 初始化 navigationController
let viewController = ViewController(nibName: nil, bundle: nil)
let navigationController = UINavigationController(rootViewController: viewController)
// 設(shè)置 window 的根控制器為 navigationController
window?.rootViewController = navigationController
// 設(shè)置 window 為主窗口并顯示出來
window?.makeKeyAndVisible()
return true
}
以下是 UINavigationController 的結(jié)構(gòu)圖:
通過 UINavigationController 進(jìn)行視圖切換的兩種常用方式:
(1)presentViewController
// 向上彈出視圖
let firstViewController = FirstViewController(nibName: nil, bundle: nil)
self.navigationController?.presentViewController(firstViewController, animated: true, completion: nil)
// 退出視圖
self.dismissViewControllerAnimated(true, completion: nil)
(2)pushViewController
// 向左推出視圖
let secondViewController = SecondViewController(nibName: nil, bundle: nil)
self.navigationController?.pushViewController(secondViewController, animated: true);
// 退出視圖
self.navigationController?.popToRootViewControllerAnimated(true)