目標(Target)與動作(Action)是iOS和OS X應用開發的中事件處理機制。
問題提出
如圖所示是一個ButtonLabelSample案例設計原型圖,其中包含一個標簽和一個按鈕,當點擊按鈕的時候,標簽文本會從初始的Label替換為HelloWorld。
ButtonLabelSample案例首先要解決的問題是:按鈕點擊事件後有誰負責響應事件?誰進行事件處理?要答這個問題,可以打開ButtonLabelSample案例故事板文件Main.storyboard,如圖所示,OK按鈕是在故事板文件Main.storyboard定義的,響應事件以及處理事件應該是在程序代碼ViewController.swift實現的。那麼如何將OK按鈕點擊事件與ViewController.swift中的事件處理代碼關聯起來?不同的計算機語言實現的方式不同,在iOS和OS X應用開發中是通過目標和動作機制實現事件處理的。
解決方案
按鈕等控件是繼承自UIControl類,具有一些高級事件,目標和動作機制就是將特地的控件事件與視圖控制器(或視圖)中方法關聯起來,這個過程稱為“定義動作事件”。“目標”是響應事件對象,為了方便訪問其他的控件狀態,這個對象一般是視圖控制器(或視圖)。“動作”是控件的事件。
ButtonLabelSample案例中按鈕是在故事板文件(或Xib文件)中定義的,響應按鈕點擊事件(動作)是在視圖控制器(目標)的方法中定義的,如下圖所示,通過定義動作事件方式把目標與動作連接起來。
要實現目標與動作的連接有兩種方式:InterfaceBuilder連線實現和編程實現。
1. Interface Builder連線實現
InterfaceBuilder連線實現就是故事板或Xib文件中,通過連線而現實。
2. 編程實現
編程實現是通過UIControl類addTarget(_:action:forControlEvents:)方法實現的,主要代碼如下:
class ViewController:UIViewController { override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor =UIColor.whiteColor() let screen =UIScreen.mainScreen().bounds; let labelWidth:CGFloat = 90 let labelHeight:CGFloat = 20 let labelTopView:CGFloat = 150 let label = UILabel(frame:CGRectMake((screen.size.width - labelWidth)/2 , labelTopView, labelWidth, labelHeight)) label.text = "Label" //字體左右劇中 label.textAlignment = .Center self.view.addSubview(label) let button = UIButton(type:UIButtonType.System)//創建UIButton對象 button.setTitle("OK",forState: UIControlState.Normal) let buttonWidth:CGFloat = 60 let buttonHeight:CGFloat = 20 let buttonTopView:CGFloat = 240 button.frame =CGRectMake((screen.size.width -buttonWidth)/2 , buttonTopView, buttonWidth, buttonHeight) button.addTarget(self, action:"onClick:", forControlEvents:UIControlEvents.TouchUpInside) self.view.addSubview(button) } func onClick(sender: AnyObject) { NSLog("OK Button onClick.") } ... }
上述代碼中創建並設置UIButton對象,其中創建UIButton對象,參數type是設置按鈕的樣式,UIButton樣式:
Custom。自定義類型。如果不喜歡圓角按鈕,可以使用該類型。
System。系統默認屬性,表示該按鈕沒有邊框,在iOS 7之前按鈕默認為圓角矩形。
Detail Disclosure。細節展示按鈕
Info Light和Info Dark。這兩個是信息按鈕
Add Contact。添加聯系人按鈕
代碼調用addTarget(_:action:forControlEvents:)方法,方法第一個參數是target,即事件處理對象,本例中是self;方法第二個參數是action,即事件處理對象中的方法,
代碼中是"onClick:",方法第三個參數是事件,TouchUpInside事件是按鈕的觸摸點擊事件。
如果調用如下無參數方法:
2func onClick() { }
調用代碼如下:
2button.addTarget(self,action: "onClick", forControlEvents:UIControlEvents.TouchUpInside)
區別在於action參數"onClick"方法名不同,action參數方法名的冒號暗示了方法名應該具有幾個參數。如果要調用的方法是如下3個參數形式:
2func onClick(sender: AnyObject, forEvent event: UIEvent) { }
那麼調用代碼如下:
2button.addTarget(self,action: "onClick:forEvent:", forControlEvents:UIControlEvents.TouchUpInside)
其中"onClick:forEvent:"是調用方法名,onClick表示方法名也是,forEvent表示第二個參數的外部參數名。