SwiftUI 里的 swift 閉包總結


創建 UI 時的閉包使用

在 SwiftUI 里閉包出現的頻率特別高,這里我重新梳理了下閉包的定義。

關於閉包

閉包表達式語法的一般形式如下:

{(parameters) -> return type in
  // 代碼
}

閉包表達式寫在花括號({})里,關鍵字in用來分隔閉包的參數、返回值與閉包體內的語句

// 傳遞閉包個 sort 方法
arr.sort(by: { (a: Int, b: Int) -> Bool in
    return a > b
})

// 閉包可以利用 Swift 的類型推斷能力,可以省略返回類型,以及參數的類型
arr.sort(by: { a, b in
    return a > b
})

// 這里移除了關鍵字return。不是所有的閉包語句都可以移除 return 關鍵字
// 這里可以是 因為只有一個表達式 (i < j)。如果存在更多表達式,那么顯式的 return 就是必需的。
arr.sort(by: { a, b in a > b })

// Swift 提供了快捷參數名,可以在內聯閉包 表達式中使用
arr.sort(by: { $0 > $1})

// 如果一個閉包是以一個函數的最后一個參數傳遞的,那么它就可以在函數的圓括號以外內聯。
arr.sort { $0 > $1 }

閉包賦值變量

// 普通方式
var str: String = "str"

// 閉包運行賦值
var str2: String = {
    return "str2"
}()

// 基於閉包原理簡化
var str3: String = {
    "str3"
}()

// 如果不需要傳遞實參,閉包體前的"="號,和末尾的"()"也可以省略
var str4: String {
    "str4"
}

SwiftUI 里的閉包

在聲明式的 UI 創建里大量使用閉包,比如

import SwiftUI

struct Text: View {
    var body: some View {
        Button(action: {
            print("Button Click")
        }) {
            Text("Hello World!")
        }
    }
}

這里創建 View、Button 都使用了閉包,看了下 Button 的實現,如下

public struct Button<Label> : View where Label : View {

    /// Creates an instance for triggering `action`.
    ///
    /// - Parameters:
    ///     - action: The action to perform when `self` is triggered.
    ///     - label: A view that describes the effect of calling `action`.
    public init(action: @escaping () -> Void, @ViewBuilder label: () -> Label)

    /// Declares the content and behavior of this view.
    public var body: some View { get }

    /// The type of view representing the body of this view.
    ///
    /// When you create a custom view, Swift infers this type from your
    /// implementation of the required `body` property.
    public typealias Body = some View
}

在 init 方法里設置了 2 個參數,都是函數類型,在使用時可以利用 swift 的 尾部閉包語法 :如果一個閉包是以一個函數的最后一個參數傳遞的,那么它就可以在函數的圓括號以外內聯,所以 Button 可以如此寫

Button(action: {
  print("Button Click")
}) {
  Text("Hello World!")
}

也可以這樣寫

Button(action: { print("Button Click") }, label: { Text("Hello World!") })


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM