當前位置:網站首頁>Swift 基礎 閉包/Block的使用(源碼)

Swift 基礎 閉包/Block的使用(源碼)

2022-06-24 08:10:31馮漢栩

一直覺得自己寫的不是技術,而是情懷,一個個的教程是自己這一路走來的痕迹。靠專業技能的成功是最具可複制性的,希望我的這條路能讓你們少走彎路,希望我能幫你們抹去知識的蒙塵,希望我能幫你們理清知識的脈絡,希望未來技術之巔上有你們也有我。

(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://cht.chowdera.com/2022/175/202206240434142177.html

隨機推薦