最近在學習Swift ,發現青玉伏案大神早期用OC寫的一篇博客-- IOS開發之自定義Button(集成三種回調模式) 很適合用來熟悉Swift的回調方式,因而我就用Swift翻版了一下,具體實現原理就很少說了,主要貼上Swift的代碼給你們看看。因爲剛開始瞭解Swift,有使用不恰當的地方請輕拍。。。。 html
上代碼:閉包
一、新建一個xib,拖一個UIView到界面上,綁定上自定義的UIView類,拖一個UILabel到view上,寫上Button僞裝是個UIButton;並將label拖到代碼當中ide
二、我這裏回調三種Button點擊事件,TouchDown、TouchUpInside、TouchUpOutside學習
A、首先是Target:代理
a、首先聲明一個枚舉來設定點擊類型指針
enum MyControlEvents{ case TouchUpInside case TouchUpOutside case TouchDown }
b、設置Target、action和Event三個屬性orm
//聲明三個屬性、添加一個addTarget方法,注意Target和delegate同樣要用weak修飾 weak var target:AnyObject? var action:Selector? var controlEvents:MyControlEvents? func addTarget(target:AnyObject!, action: Selector!, forMyControlEvents controlEvents: MyControlEvents! ){ self.target = target self.action = action self.controlEvents = controlEvents }
c、在touch事件的代理裏面實現Target方法、並把label的顏色改改,這樣纔像button,我把代理方法寫在了extension延展裏面,由於我見蘋果都這樣htm
extension MyViewButton{ override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { self.titleLabel.textColor = UIColor.lightGrayColor() if self.controlEvents == MyControlEvents.TouchDown{ self.target?.performSelector(self.action!, withObject: self) } } override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { self.titleLabel.textColor = UIColor.blueColor() //let point:CGPoint = (touches as NSSet).anyObject()!.locationInView(self)、下面方法的合體 let view = (touches as NSSet).anyObject() let point:CGPoint = view!.locationInView(self) //判斷Target類型和觸摸點移出狀況相匹配時執行target方法
if CGRectContainsPoint(self.bounds, point) && self.controlEvents == MyControlEvents.TouchUpInside{ self.target?.performSelector(self.action!, withObject: self) }else if !CGRectContainsPoint(self.bounds, point) && self.controlEvents == MyControlEvents.TouchUpOutside{ self.target?.performSelector(self.action!, withObject: self) } }
d、在VC中實現,選擇不一樣的點擊類型便可監控不一樣的點擊事件啦blog
class ViewController: UIViewController , MyViewButtonDelegate { var myButton:MyViewButton? override func viewDidLoad() { super.viewDidLoad() //從xib中加載咱們自定義的view,個人xib叫作「View」 let bundel:NSBundle = NSBundle.mainBundle() let views:Array = bundel.loadNibNamed("View", owner: nil, options: nil) self.myButton = views.last as? MyViewButton self.myButton?.frame = CGRectMake(80, 200, 200, 100) self.view.addSubview(self.myButton!) self.myButton?.addTarget(self, action: Selector!("didTapButton:"), forMyControlEvents: MyControlEvents.TouchUpInside) }
最後 實現點擊方法便可事件
func didTapButton(button:MyViewButton){ print("VC點擊了按鈕---點擊類型是\(button.controlEvents)") }
B、協議
一、聲明一個protocol,裏面有三個可選實現的方法,並把自身當作參數帶出去
objc protocol MyViewButtonDelegate:NSObjectProtocol{ optional func didTouchMyButton(button:MyViewButton) optional func didTouchUpInsideButton(button:MyViewButton) optional func didTouchUpOutsideButton(button:MyViewButton) }
二、聲明一個delegate屬性,一樣是弱指針引用
weak var delegate:MyViewButtonDelegate!
三、一樣在touch事件中實現
extension MyViewButton{ //調用協議方法時判斷一下delegate和協議方法是否存在 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { self.titleLabel.textColor = UIColor.lightGrayColor() if self.delegate != nil && self.delegate!.respondsToSelector("didTouchMyButton:"){ self.delegate?.didTouchMyButton!(self) } } override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { self.titleLabel.textColor = UIColor.blueColor() //let point:CGPoint = (touches as NSSet).anyObject()!.locationInView(self) let view = (touches as NSSet).anyObject() let point:CGPoint = view!.locationInView(self) if CGRectContainsPoint(self.bounds, point){ if self.delegate != nil && self.delegate!.respondsToSelector("didTouchUpInsideButton:"){ self.delegate?.didTouchUpInsideButton!(self) } }else{ if self.delegate != nil && self.delegate!.respondsToSelector("didTouchUpOutsideButton:"){ self.delegate?.didTouchUpOutsideButton!(self) } } } }
四、在VC中實現便可
class ViewController: UIViewController , MyViewButtonDelegate { override func viewDidLoad() { super.viewDidLoad() let bundel:NSBundle = NSBundle.mainBundle() let views:Array = bundel.loadNibNamed("View", owner: nil, options: nil) self.myButton = views.last as? MyViewButton self.myButton?.frame = CGRectMake(80, 200, 200, 100) self.view.addSubview(self.myButton!) //設置button的代理 self.myButton!.delegate = self } extension ViewController{ //實現代理方法 func didTouchMyButton(button: MyViewButton) { print("delegate--VC點擊了button") } func didTouchUpInsideButton(button: MyViewButton) { print("delegate--TouchUpInside") } func didTouchUpOutsideButton(button: MyViewButton) { print("delegate--TouchUpOutside") } }
C、閉包(block)
一、首先在自定義view裏實現,至關於typedef一個block類型
typealias MyBlock = (button:MyViewButton)->Void
二、聲明三個block屬性,而且聲明三個給block賦值方法
var TouchBlockHandel:MyBlock? var TouchUpInsideBlockHandel:MyBlock? var TouchUpOutsideBlockHandel:MyBlock? //也能夠不寫方法直接屬性賦值 func setMyTouchBlock(block:MyBlock){ self.TouchBlockHandel = block } func setMyTouchUpInsideBlock(block:MyBlock){ self.TouchUpInsideBlockHandel = block } func setMyTouchUpOutsideBlock(block:MyBlock){ self.TouchUpOutsideBlockHandel = block }
三、在touch事件中實現block
extension MyViewButton{ override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { self.titleLabel.textColor = UIColor.lightGrayColor() self.TouchBlockHandel!(button: self) } override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { self.titleLabel.textColor = UIColor.blueColor() //let point:CGPoint = (touches as NSSet).anyObject()!.locationInView(self) let view = (touches as NSSet).anyObject() let point:CGPoint = view!.locationInView(self) if CGRectContainsPoint(self.bounds, point){ self.TouchUpInsideBlockHandel!(button: self) }else{ self.TouchUpOutsideBlockHandel!(button: self) } }
四、一樣在VC中給三個block賦值便可
class ViewController: UIViewController , MyViewButtonDelegate { var myButton:MyViewButton? override func viewDidLoad() { super.viewDidLoad() let bundel:NSBundle = NSBundle.mainBundle() let views:Array = bundel.loadNibNamed("View", owner: nil, options: nil) self.myButton = views.last as? MyViewButton self.myButton?.frame = CGRectMake(80, 200, 200, 100) self.view.addSubview(self.myButton!) self.myButton?.setMyTouchBlock({ (button:MyViewButton) -> Void in print("block--VC點擊了button") }) self.myButton?.setMyTouchUpInsideBlock({ (button:MyViewButton) -> Void in print("block--VCTouchUpInside") }) self.myButton?.setMyTouchUpOutsideBlock({ (button:MyViewButton) -> Void in print("block--VCTouchUpOutside") }) } }
最後來看看三個方法寫在一塊兒的打印結果。就添加了一個target監控TouchUpInside。整體來講和OC邏輯沒有任何變化,只是語法上有所不一樣,block仍是好用