类似于Objective-C中把block作为属性进行传值一样,swift也可以通过把闭包作为属性传值。
它的写法是这样的:
swift中的闭包和block在作为回调使用的时候用法稍有不同,因为它并不能直接作为属性被使用方调用。为了探究它是怎么用的,我研究了一下SnapKit中的闭包是怎么写的。现在假设B页面要把值回调给A页面,在B页面代码中要创建一个私有的属性闭包,然后写一个共有的方法用来接收传进来的闭包并把传进来的闭包给该私有属性闭包赋值。然后在A页面调用B的这个公有方法即可。
为了说明问题我做了一个demo,点击A页面会跳转到B页面,然后B页面上有2个按钮,点击这两个按钮会跳回到A页面并触发回调。
效果图如下所示:
为了说明问题我是用可视化编程组件来写UI的。
A页面代码如下所示:
//
// ViewController.swift
// swift之属性闭包回调
//
// Created by Stroman on 2017/8/19.
// Copyright © 2017年 Stroman. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
//生命周期方法与本demo无关
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//等待回调
@IBAction func tapAction(_ sender: UITapGestureRecognizer) {
let bViewController:BViewController = self.storyboard?.instantiateViewController(withIdentifier: "BViewController") as! BViewController
bViewController.tranferNoParameterClosure { (Void) in
print("无参回调了")
}
bViewController.tranferParameterClosure { (string) in
print(string)
}
self.present(bViewController, animated: true, completion: nil)
}
}
B页面的代码如下所示:
//
// BViewController.swift
// swift之属性闭包回调
//
// Created by Stroman on 2017/8/19.
// Copyright © 2017年 Stroman. All rights reserved.
//
import UIKit
class BViewController: UIViewController {
//公有的闭包
private var noParameterEnclosure:((Void) -> Void)?
private var parameterEnclosure:((String) -> Void)?
//用来传闭包的公有接口。
public func tranferNoParameterClosure(callbackEnclosure:@escaping ((Void) -> Void)) {
self.noParameterEnclosure = callbackEnclosure
}
public func tranferParameterClosure(callbackEnclosure:@escaping ((String) -> Void)) {
self.parameterEnclosure = callbackEnclosure
}
//在dismiss的时候回调
@IBAction func parameterAction(_ sender: UIButton) {
if self.parameterEnclosure != nil {
self.parameterEnclosure!("有参传值了")
}
self.dismiss(animated: true, completion: nil)
}
@IBAction func noParameterAction(_ sender: UIButton) {
if self.noParameterEnclosure != nil {
self.noParameterEnclosure!()
}
self.dismiss(animated: true, completion: nil)
}
//生命周期方法与本demo无关
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}