当前位置:网站首页>Swift 基础 闭包/Block的使用(源码)

Swift 基础 闭包/Block的使用(源码)

2022-06-24 06:55:00 冯汉栩

一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。

(Swift)闭包作为属性–源码下载地址

(Swift)闭包作为方法参数–源码下载地址

(Swift)闭包构造函数–源码下载地址

前言

今年2022年又用回了swift语言,4年前用过,已经很久没有用了,会想起来还是需要时间来适应的。毕竟swift的使用比oc灵活多了,下面记录一下我平时使用闭包的使用

之前我也oc语言使用block的文章
OC 监听-Block/代理/通知/KVO(源码)

和block使用容易产生循环应用的问题
OC 技术 Block循环引用的问题(视频)(代码)

正题

闭包最常见就是用于数据的逆传

闭包作为属性的使用

有值的VC

1.创建一个闭包出来
在这里插入图片描述
在有值的方法里面调用闭包,把值传递到闭包里面
在这里插入图片描述
点击按键出发方法,就像网络请求数据一样
在这里插入图片描述

import UIKit

class BViewController: UIViewController {
    
    let btn = UIButton()

    // 重定义闭包类型
    typealias StudentCallBlock = (_ name:String, _ age:String, _ gengder:String) -> ()
    
    // 创建闭包属性
    var studentCallBlock:StudentCallBlock?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        view.addSubview(btn)
        btn.addTarget(self, action: #selector(btnClick), for: .touchUpInside)
        btn.setTitle("pop", for: .normal)
        btn.titleLabel?.font = .systemFont(ofSize: 14)
        btn.setTitleColor(.white, for: .normal)
        btn.backgroundColor = .orange
        btn.frame = CGRect(x: 100, y: 250, width: 50, height: 50)
     
    }
    
    //有数据方法
    private func getDate(){
        let name = "juan"
        let age = "12"
        let gender = "gril"
        //把数据传递到闭包里面保存起来
        studentCallBlock!(name,age,gender)//如果外面不实现闭包会崩掉
    }
    
    @objc private func btnClick() {
        //模拟获取网络数据
        getDate()
        navigationController?.popViewController(animated: true)
    }

}

想得到值的控制器

通过对象点出属性可以拿到传出来的值
在这里插入图片描述

import UIKit
import SnapKit

class ViewController: UIViewController {

    let btn_0 = UIButton()
    let btn_1 = UIButton()
    let vc = BViewController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
    
        view.addSubview(btn_0)
        btn_0.addTarget(self, action: #selector(btnClick), for: .touchUpInside)
        btn_0.setTitle("dump", for: .normal)
        btn_0.titleLabel?.font = .systemFont(ofSize: 14)
        btn_0.setTitleColor(.white, for: .normal)
        btn_0.backgroundColor = .orange
        btn_0.frame = CGRect(x: 100, y: 250, width: 50, height: 50)
        
        vc.studentCallBlock = { name, age, gengder in
            print("studentCallBlock name: \(name), age: \(age), gengder: \(gengder),")
        }
    }

    @objc private func btnClick() {
        navigationController?.pushViewController(vc, animated: true)
    }
}

闭包作为方法参数

有值的控制器

定义闭包的类型
在这里插入图片描述

创建一个带闭包参数的方法,使用闭包把值传递出去
在这里插入图片描述

import UIKit

class BViewController: UIViewController {
    
    // 重定义闭包类型
    typealias StudentCallBlock = (_ name:String, _ age:String, _ gengder:String) -> ()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
    }
    
    //把Block放到方法里面,用于外面调用得到值
    func userBlock(callBlock: @escaping StudentCallBlock){
        callBlock("name","age","gender")
    }
}

想得到值的控制器

点击按键调用对象的闭包当法,就可以得到传递出来的值
在这里插入图片描述

import UIKit
import SnapKit

class ViewController: UIViewController {

    let btn_1 = UIButton()
    let vc = BViewController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        view.addSubview(btn_1)
        btn_1.addTarget(self, action: #selector(btnClick_1), for: .touchUpInside)
        btn_1.setTitle("value", for: .normal)
        btn_1.titleLabel?.font = .systemFont(ofSize: 14)
        btn_1.setTitleColor(.white, for: .normal)
        btn_1.backgroundColor = .orange
        btn_1.frame = CGRect(x: 100, y: 450, width: 50, height: 50)             
    }

    @objc private func btnClick_1() {
        vc.userBlock { name, age, gengder in
            print("userBlock name: \(name), age: \(age), gengder: \(gengder),")
        }
    }
}

闭包写在构造函数

有时候看到一些别人的写法,闭包写在构造函数里面,一般一个控制器面需要弹出一个view的选择框,然后选择好之后把想要的信息传递出来可以这么用。

有值的控制器

定义闭包形式
在这里插入图片描述
在构造函数里面,把闭包关联起来
在这里插入图片描述
出发闭包的地方把值传递出去
在这里插入图片描述

import UIKit

public let kScreenWidth: CGFloat = UIScreen.main.bounds.size.width

public let kScreenHeight: CGFloat = UIScreen.main.bounds.size.height

class FloatView: UIView {

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    init(with valueBlock:((NSInteger)->())?) {
        
        self.valueBlock = valueBlock
        
        let targetRect = CGRect(
            x: 0,
            y: 0,
            width: kScreenWidth,
            height: kScreenHeight
        )
        
        super.init(frame: targetRect)
        
        buildUI()
    }
    
    func showView(){
        UIView.animate(withDuration: 0.5, animations: {
            self.backgroundColor = .black.withAlphaComponent(0.5)
        })
    }
    
    func dismissView(){
        valueBlock?(1)
        
        self.removeFromSuperview()
        backgroundColor = .clear
    }
    
    private let button = UIButton()
    
    private var valueBlock:((_ index:NSInteger)->())?
    
    private var list = [String]()
    
    private func buildUI(){
        backgroundColor = .clear
        
        addSubview(button)
        button.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight)
        button.addTarget(self, action: #selector(buttonClick), for: .touchUpInside)
    }
    
    @objc func buttonClick() {
        self.dismissView()
    }
}

想得到值的控制器

闭包在构造函数的参数里面打印想得到的值
在这里插入图片描述
点击按键把闭包的地传递出来
在这里插入图片描述

import UIKit
import SnapKit

class ViewController: UIViewController {

    let btn_0 = UIButton()
    
    let container = FloatView { index in
        print("index: \(index)")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
    
        view.addSubview(btn_0)
        btn_0.addTarget(self, action: #selector(btnClick), for: .touchUpInside)
        btn_0.setTitle("dump", for: .normal)
        btn_0.titleLabel?.font = .systemFont(ofSize: 14)
        btn_0.setTitleColor(.white, for: .normal)
        btn_0.backgroundColor = .orange
        btn_0.frame = CGRect(x: 100, y: 250, width: 50, height: 50)
           
        view.addSubview(container)
        container.showView()
    }

    @objc private func btnClick() {
        container.dismissView()
    }
    
}
原网站

版权声明
本文为[冯汉栩]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_38716347/article/details/125351173