创建 UI 时的闭包使用

在 SwiftUI 里闭包出现的频率特别高,这里我重新梳理了下闭包的定义。

关于闭包

闭包表达式语法的一般形式如下:

  1. {(parameters) -> return type in
  2. // 代码
  3. }

闭包表达式写在花括号({})里,关键字in用来分隔闭包的参数、返回值与闭包体内的语句

  1. // 传递闭包个 sort 方法
  2. arr.sort(by: { (a: Int, b: Int) -> Bool in
  3. return a > b
  4. })
  5. // 闭包可以利用 Swift 的类型推断能力,可以省略返回类型,以及参数的类型
  6. arr.sort(by: { a, b in
  7. return a > b
  8. })
  9. // 这里移除了关键字return。不是所有的闭包语句都可以移除 return 关键字
  10. // 这里可以是 因为只有一个表达式 (i < j)。如果存在更多表达式,那么显式的 return 就是必需的。
  11. arr.sort(by: { a, b in a > b })
  12. // Swift 提供了快捷参数名,可以在内联闭包 表达式中使用
  13. arr.sort(by: { $0 > $1})
  14. // 如果一个闭包是以一个函数的最后一个参数传递的,那么它就可以在函数的圆括号以外内联。
  15. arr.sort { $0 > $1 }

闭包赋值变量

  1. // 普通方式
  2. var str: String = "str"
  3. // 闭包运行赋值
  4. var str2: String = {
  5. return "str2"
  6. }()
  7. // 基于闭包原理简化
  8. var str3: String = {
  9. "str3"
  10. }()
  11. // 如果不需要传递实参,闭包体前的"="号,和末尾的"()"也可以省略
  12. var str4: String {
  13. "str4"
  14. }

SwiftUI 里的闭包

在声明式的 UI 创建里大量使用闭包,比如

  1. import SwiftUI
  2. struct Text: View {
  3. var body: some View {
  4. Button(action: {
  5. print("Button Click")
  6. }) {
  7. Text("Hello World!")
  8. }
  9. }
  10. }

这里创建 View、Button 都使用了闭包,看了下 Button 的实现,如下

  1. public struct Button<Label> : View where Label : View {
  2. /// Creates an instance for triggering `action`.
  3. ///
  4. /// - Parameters:
  5. /// - action: The action to perform when `self` is triggered.
  6. /// - label: A view that describes the effect of calling `action`.
  7. public init(action: @escaping () -> Void, @ViewBuilder label: () -> Label)
  8. /// Declares the content and behavior of this view.
  9. public var body: some View { get }
  10. /// The type of view representing the body of this view.
  11. ///
  12. /// When you create a custom view, Swift infers this type from your
  13. /// implementation of the required `body` property.
  14. public typealias Body = some View
  15. }

在 init 方法里设置了 2 个参数,都是函数类型,在使用时可以利用 swift 的 尾部闭包语法 :如果一个闭包是以一个函数的最后一个参数传递的,那么它就可以在函数的圆括号以外内联,所以 Button 可以如此写

  1. Button(action: {
  2. print("Button Click")
  3. }) {
  4. Text("Hello World!")
  5. }

也可以这样写

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

SwiftUI 里的 swift 闭包总结的更多相关文章

  1. Swift闭包概念与常见使用场景总结

    ·Swift 闭包 闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值. Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些 ...

  2. Swift --闭包表达式与闭包(汇编分析)

    在Swift中,可以通过func定义一个函数,也可以通过闭包表达式定义一个函数! 一.闭包表达式 概念 闭包表达式与定义函数的语法相对比,有区别如下: 去除了func 去除函数名 返回值类型添加了关键 ...

  3. Swift 闭包的简单学习

    OC中已经学习了闭包 在swift里面 该怎么处理 不多说 上代码 //(num:Int) ->Bool是闭包的参数类型 func hasCloserMatch(arr :[Int], valu ...

  4. [译]理解 SwiftUI 里的属性装饰器@State, @Binding, @ObservedObject, @EnvironmentObject

    原文地址:https://mecid.github.io/2019/06/12/understanding-property-wrappers-in-swiftui/ @States 通过使用 @St ...

  5. swift 闭包循环引用

    当使用闭包时,类本身持有self,然后又在闭包中访问了self或者self的属性,就会导致恶心额循环引用.swift提供的解决方法是在闭包中定义捕获列表,捕获列表是闭包想怎么引用捕获来的变量.例如下面 ...

  6. swift 闭包

    闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 这就是所谓的闭合并包裹着 这些常量和变量,俗称闭包. Swift标准库中提供了sort排序函数,sort函数的第二个参数是个闭包.和OC中的bl ...

  7. [ios][swift]使用swift闭包进行viewcontroller反向传值

    闭包参考:http://c.biancheng.net/cpp/html/2285.html   闭包详解 传值参考:http://www.tuicool.com/articles/vy2uUz Sw ...

  8. swift 闭包+嵌套函数+extension+单例+嵌套函数+??

    //: Playground - noun: a place where people can play import UIKit //*******************嵌套函数********* ...

  9. swift 闭包简写实际参数名$0、$1等理解

    Swift 自动对行内闭包提供简写实际参数名,你也可以通过 $0 , $1 , $2 等名字来引用闭包的实际参数值. 如果你在闭包表达式中使用这些简写实际参数名,那么你可以在闭包的实际参数列表中忽略对 ...

随机推荐

  1. Linux内核设计与实现 总结笔记(第十四章)块I/O层

    一.剖析一个块设备 块设备最小的可寻址单元是扇区. 扇区大小一般是2的整数倍,最常见的是512字节. 因为各种软件的用途不同,所以他们都会用到自己的最小逻辑可寻址单元----块.块只能基于文件系统,是 ...

  2. Bugku 杂项 telnet

    letnet 下载zip后发现是一个数据包,放到wireshark中打开 右键追踪tcp流后可以发现flag

  3. 计蒜客 T2237 魔法 分类讨论

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...

  4. 微信小程序自定义底部导航栏组件+跳转

    微信小程序本来封装有底部导航栏,但对于想自定义样式和方法的开发者来说,这并不是很好. 参考链接:https://github.com/ljybill/miniprogram-utils/tree/ma ...

  5. 170829-关于AOP面向切面编程

    1.AOP概念:Aspect Oriented Programming 面向切面编程 2.作用:本质上来说是一种简化代码的方式 继承机制 封装方法 动态代理  …… 3.情景举例 ①数学计算器接口[M ...

  6. 学习wavenet_vocoder之预处理、训练

    一.预处理 1.在进行预处理时,如果不明白需要的参数,可以使用命令获取帮助,从这里我们可以看到可以具体的用法和对应的参数. python preprocess.py --help python pre ...

  7. [CSP-S模拟测试]:老司机的狂欢(LIS+LCA)

    题目背景 光阴荏苒.不过,两个人还在,两支车队还在,熟悉的道路.熟悉的风景,也都还在.只是,这一次,没有了你死我活的博弈,似乎和谐了许多.然而在机房是不允许游戏的,所以班长$XZY$对游戏界面进行了降 ...

  8. 任何国家都无法限制数字货币。为什么呢? 要想明白这个问题需要具备一点区块链的基础知识: 区块链使用的大致技术包括以下几种: a.点对点网络设计 b.加密技术应用  c.分布式算法的实现 d.数据存储技术 e.拜占庭算法 f.权益证明POW,POS,DPOS 原因一: 点对点网络设计 其中点对点的P2P网络是bittorent ,由于是点对点的网络,没有中心化,因此在全球分布式的网

    任何国家都无法限制数字货币.为什么呢? 要想明白这个问题需要具备一点区块链的基础知识: 区块链使用的大致技术包括以下几种: a.点对点网络设计 b.加密技术应用  c.分布式算法的实现 d.数据存储技 ...

  9. Retina 屏幕与二倍图

    分辨率 屏幕分辨率:指屏幕可显示的像素的个数 图像分辨率:位图图像包含的像素的个数 对于 Retina 屏它的分辨率是传统屏的两倍,而屏幕大小没有变化,所以它需要的图片的分辨率应该是传统屏幕的两倍(甚 ...

  10. Delphi XE2 之 FireMonkey 入门(18) - TLang(多语言切换的实现)

    一个小小的 TLang 类, 实现多语言切换, 挺好的. 它的工作思路是: 1.首先通过 AddLang('语言代码') 添加语言类别, 如: AddLang('en').AddLang('cn'). ...