最近在學習Swift ,發現青玉伏案大神早期用OC寫的一篇博客--IOS開發之自定義Button(集成三種回調模式) 很適合用來熟悉Swift的回調方式,於是我就用Swift翻版了一下,具體實現原理就不多說了,主要貼上Swift的代碼給大家看看。由於剛開始了解Swift,有使用不恰當的地方請輕拍。。。。
上代碼:
1、新建一個xib,拖一個UIView到界面上,綁定上自定義的UIView類,拖一個UILabel到view上,寫上Button假裝是個UIButton;並將label拖到代碼當中


2、我這里回調三種Button點擊事件,TouchDown、TouchUpInside、TouchUpOutside
A、首先是Target:
a、首先聲明一個枚舉來設定點擊類型
enum MyControlEvents{
case TouchUpInside
case TouchUpOutside
case TouchDown
}
b、設置Target、action和Event三個屬性
//聲明三個屬性、添加一個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延展里面,因為我見蘋果都這樣
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中實現,選擇不同的點擊類型即可監控不同的點擊事件啦
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、協議
1、聲明一個protocol,里面有三個可選實現的方法,並把自身當做參數帶出去
objc protocol MyViewButtonDelegate:NSObjectProtocol{
optional func didTouchMyButton(button:MyViewButton)
optional func didTouchUpInsideButton(button:MyViewButton)
optional func didTouchUpOutsideButton(button:MyViewButton)
}
2、聲明一個delegate屬性,同樣是弱指針引用
weak var delegate:MyViewButtonDelegate!
3、同樣在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)
}
}
}
}
4、在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)
1、首先在自定義view里實現,相當於typedef一個block類型
typealias MyBlock = (button:MyViewButton)->Void
2、聲明三個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
}
3、在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)
}
}
4、同樣在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還是好用

好了,這樣就結束了,今天下雪了,大家注意保暖!
