iOS_Swift初识之使用三种回调方式自定义Button
最近在学习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还是好用

好了,这样就结束了,今天下雪了,大家注意保暖!
iOS_Swift初识之使用三种回调方式自定义Button的更多相关文章
- 通过三个DEMO学会SignalR的三种实现方式
一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...
- Service组件 总结 + 绑定理Service三种实现方式 Messager + Binder + AIDL
在Android中进程按优先级可以分为五类,优先级从高到低排列: - 前台进程 该进程包含正在与用户进行交互的界面组件,比如一个Activity - 可视进程 该进程中的组件虽然没有和用户交互,但是仍 ...
- Android平台中实现对XML的三种解析方式
本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...
- Spring IOC以及三种注入方式
IOC是spring的最基础部分,也是核心模块,Spring的其他组件模块和应用开发都是以它为基础的.IOC把spring的面向接口编程和松耦合的思想体现的淋漓尽致. IOC概念 IOC(Invers ...
- C# 三种打印方式含代码
一:C#代码直接打印pdf文件(打印质保书pdf文件) 引用: 代码注释很详细了. private void btn_pdf_Click(object sender, RoutedEventArgs ...
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 异常汇总:http://www ...
- python笔记-20 django进阶 (model与form、modelform对比,三种ajax方式的对比,随机验证码,kindeditor)
一.model深入 1.model的功能 1.1 创建数据库表 1.2 操作数据库表 1.3 数据库的增删改查操作 2.创建数据库表的单表操作 2.1 定义表对象 class xxx(models.M ...
- 延迟加载(Lazyload)三种实现方式
定义:延迟加载也称为惰性加载,即在长网页中延迟加载图像.用户滚动到它们之前,视口外的图像不会加载.这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快.在某些情况下,它还可以帮助减少服务器负载. ...
- 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)
摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...
随机推荐
- 浅谈sizeof
问题:1)sizeof是函数吗:2)sizeof功能:3)具体问题下sizeof值 1)sizeof不是函数,是C语言的一个关键字 2)sizeof作为右值时,求①某个数据类型(sizeof(int) ...
- jquery mobile上传图片完整例子(包含ios图片横向问题处理和C#后台图片压缩)
上传图片本身是个基本的小功能,但是到了移动端就不那么简单了,相信找到这篇文章的你一定有深深的同感. 本文实例是:在(移动端)页面中点击图片,然后选择文件,然后保存.使用Asp.net 难点一:后台获取 ...
- IOS导航栏颜色渐变与常用属性
(转:http://www.cnblogs.com/Lingchen-start/archive/2015/10/23/4904361.html) 今年很忙,忙的写日志的时间都很少. 少的可怜. 自 ...
- 使用Windows Form 制作一个简易资源管理器
自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始 ...
- ie11浏览器和chrome浏览器对于bgsound和background的一些区别
今天在编写一个非常简单的网页的时候,按照书上写的,使用了一个jpg图片作为背景图片,用background属性放在<body>标签内,同时使用<bgsound>标签插入背景音乐 ...
- 关于mongoldb 启动时显示 add already in use
1 .不要在国内网上查找 浪费时间 2. stack over flow 是个不错的选择 进入正题. 终端输入: ps wuax | grep mongo 会看到: 随后:kill 447
- 第7章 LED将为我闪烁:控制发光二极管
所谓I/O内存是通过各种接口连接到主机的硬件在主机内存的映射.LED驱动还提供了两种交互方式:命令和读写设备文件. 创建设备文件的步骤: 第1步:使用cdev_init函数初始化cdev 第2步:指定 ...
- SE1-soc入手又有的东西可以玩了
笔者之前只有DE2-35 和DE2-70 两个板子用,相比之下亮点主要是:配备了DDR3 的存储器,视频处理能处理更高帧频和画幅数了,此外直接有了USB2.0接口,还配有A9 Arm双核芯片,功能一下 ...
- navicat在ubuntu下中文乱码的真正解决方法ZT
乱码解决方法(自己解决我自己这种情况之后打猜测): 打开start_navicat文件,会看到 export LANG="en_US.UTF-8" 将这句话改为 export LA ...
- 参数*args和**args区别
#*args(元组)和**args(字典)的区别 def tuple_test(*args): for i in args: print 'hello'+i s=('xuexi','mili') tu ...