swift 代理声明

2019-02-13 18:15:28 Future_One 阅读数 998

前言

    代理是一种设计模式。它允许类(或者Swift中结构体)将自身负责的功能委托给其他的类型的实例示例。

应用

接下来举一个列子

  1. 代理实现的VC
import UIKit

class ViewController: UIViewController,SecondVCDelegate{
   
    @IBOutlet weak var showNameL: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    @IBAction func nextBtnAction(_ sender: Any) {
        let nextVC : SecondVC = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "nextVC") as! SecondVC
        nextVC.delegate = self
        self.present(nextVC, animated: true, completion: nil)
        
    }
    
    @objc func saveName(_ nameStr: String) {
        self.showNameL.text = "请输入姓名:\(nameStr)"
        print("---------------------\(nameStr)")
    }
    
    
}

在这里插入图片描述

  1. SecondVC
import UIKit

class SecondVC: UIViewController {
    weak var delegate : SecondVCDelegate?
    @IBOutlet weak var inputName: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func btnSureAction(_ sender: Any) {
        if self.delegate != nil && (self.delegate?.responds(to: Selector.init(("saveName:"))))!{
            self.delegate?.saveName(inputName.text!)
        }
        
        self.dismiss(animated: true, completion: nil)
    }
    
}

protocol SecondVCDelegate : NSObjectProtocol {
    func saveName(_ nameStr : String)
}

在这里插入图片描述

Swift中Delegate细节注意

一、需要用weak修饰代理(weak var SecondVCDelegate?)

weak修饰声明的属性避免循环引用的问题(类似OC中的weak修饰)

二、代理方法的判断(respondsToSelector()在Swift中的使用)

原因是在OC的代码中, 用respondsToSelector()方法来判断是否实现了方法。
而在Swift中需要使用 (self.delegate?.responds(to: Selector.init((“saveName:”))))! 的方式判断是否实现这个方法。

在在代理执行的类中需要使用@objc 修饰saveName方法。(@objc 关键字来达到,Objective-C中使用#selector中使用)

Swift Delegate详解的: Demo地址
https://github.com/FlameDream/Delegate_Test

2017-05-14 14:54:17 PancrasBohemian 阅读数 631

代理 是iOS 开发里面一个很重要的内容,在关键时刻可以发挥重要作用,实训中使用到的例子是:* 点击一个tableviewcell中的一个按钮,跳转到另一个页面 *
如果简单的话当然可以直接storyboard连接过去,但是如果想使用NavigationController,你总不能在button的Selector里面写self.navigationcontroller吧,因为self是一个cell,没有导航控制器,那么我们这个时候可以使用委托。
我们首先来看一下委托的概念。


委托(delegate)是Cocoa的一个术语,表示将一个对象的部分功能转交给另一个对象。
比如对象A希望对象B知道将要发生或已经发生某件事情,对象A可以把对象B的引用存为一个实例变量。这个对象B称为委托。当事件发生时,它检查委托对象是否实现了与该事件相适应的方法。如果已经实现,则调用该方法。
由于松耦合的原因,一个对象能成为多个对象的委托。某些情况下,相较于通过继承让子类实现相关的处理方法,可以有效减少代码复杂度。所以iOS中也大量的使用了委托。


首先在cell的类定义前面加一个协议的定义,并在类定义中增加delegate的一个变量

protocol RequestJumpDelegate {
    func requestJump()
}

class DemoCell: FoldingCell {
    var delegate: RequestJumpDelegate?
//其他代码
}

随后给DemoCell里面的按钮增加方法绑定,方法调用的是协议中的requsetJump()

    @IBAction func requestTapped(_ sender: Any) {
            delegate?.requestJump()
    }

随后在使用了cell的VC里面定义好requsetJump()方法,并将cell的delegate设为自己,即可完成任务。

2016-04-10 20:11:59 xyx340521 阅读数 417

swift中的代理声明和OC中差不多。

使用关键字protocol 定义代理的名称在大括号里面写上代理要实现的方法,func 方法名(参数: 参数类型)->返回值类型

protocol  CustomLayOutDelegate{

    func CollectionCellSize(collectionView :UICollectionView,layout : CustomLayOut ,indexPath :NSIndexPath) ->CGSize 

}

class CustomLayOut: UICollectionViewFlowLayout {

声明属性

var delegate : CustomLayOutDelegate?

在代理对象里调用

接收代理

class ViewController: UIViewController,CustomLayoutDelegate,UICollectionViewDelegate,UICollectionViewDataSource{

    var collectionView :UICollectionView?

    

    overridefunc viewDidLoad() {

        super.viewDidLoad()

        self.view.backgroundColor =UIColor.whiteColor();

        let  layOut :CustomLayout = CustomLayout.init(numberOfColumns:2);

设置代理对象

        layOut.delegate =self;

实现代理方法

  func collectionView(collectionView:UICollectionView!, layout: CustomLayout!, sizeForItemAtIndexPath indexPath:NSIndexPath!) -> CGSize {

        returnCGSizeMake(width, height);

    }


2017-06-15 17:49:37 m0_37936183 阅读数 534

委托是一种设计模式

它允许类或结构体将一些需要它们负责的功能委托给其他类型的实例。委托模式的实现很简单:定义协议来封装那些需要被委托的功能,这样就能确保遵循协议的类型能提供这些功能。委托模式可以用来响应特定的动作,或者接收外部数据源提供的数据,而无需关心外部数据源的类型。

//申明代理
protocol LookBabyDelegate{

   func feed()
}
//保姆遵循代理
class BaoMu: LookBabyDelegate {

    init() {

    }

    func feed() {
        print("Baby is Full")
    }


}
//baby 声明代理 并且实现代理方法
class Baby {

    var delegate : LookBabyDelegate?

    init() {

    }

    func cry() {
        if let delet = delegate {
            delet.feed()
        }
    }

}

let baomu = BaoMu()

var baby = Baby()

baby.delegate = baomu

baby.cry()

1.先声明 一个照顾baby的协议,
2. 保姆遵循照顾协议
3. 将baby的代理设为保姆
4. 调用baby.cry() 就可以调用 保姆里面的协议方法
最后log 如下

log ---- Baby is Full
Program ended with exit code: 0

协议的合成

有时候需要同时遵循多个协议,你可以将多个协议采用 SomeProtocol & AnotherProtocol 这样的格式进行组合,称为 协议合成(protocol composition)。你可以罗列任意多个你想要遵循的协议,以与符号( & )分隔。

protocol Named {
    var name: String { get }
}
protocol Aged {
    var age: Int { get }
}
struct Person: Named, Aged {
    var name: String
    var age: Int
}
func wishHappyBirthday(to celebrator: Named & Aged) {
    print("Happy birthday, \(celebrator.name), you're \(celebrator.age)!")
}
let birthdayPerson = Person(name: "Malcolm", age: 21) wishHappyBirthday(to: birthdayPerson)
// 打印 “Happy birthday Malcolm - you're 21!”

协议合成并不会生成新的、永久的协议类型,而是将多个协议中的要求合成到一个只在局部作用域有效的临时协议中(做限制类型使用)。

2017-01-12 19:25:14 Mazy_ma 阅读数 2329

虽然 Swift 中闭包的功能非常强大, 但代理也不可替代, 各有各的好处, 合适的, 才是最好的!


个人总结, 代理的使用需要五个步骤:

  • 1.设置代理协议,定义可选或者必选方法
  • 2 声明一个delegate属性
  • 3 过滤代理,实现代理方法
  • 4 接收代理
  • 5 实现代理方法

具体实现步骤如下:

设置代理控制器需要做的事

1 设置代理协议,定义可选或者必选方法

@objc protocol XMTestDelegate {

   /// 定义可选方法
   @objc optional func sendDataToBack(str: String)

   /// 定义必选方法
   func sendData2Back(str: String)

}

2 声明一个delegate属性,用可选项代替”weak”,防止循环引用

    var delegate: XMTestDelegate?

3 过滤代理,实现代理方法

   if delegate != nil {

       delegate?.sendData2Back(str: "goodBye 2016")
       delegate?.sendDataToBack!(str: "hello 2017")

    }

接收代理控制器需要做的事

4 接收代理

     testVC.delegate = self

5 实现代理方法


extension XMTestViewController: XMTestDelegate {

    func sendDataToBack(str: String) {
        print(str) // hello 2017
    }

    func sendData2Back(str: String) {
        print(str) // goodBye 2016
    }

}

Swift 代理传值

阅读数 648