swift @State @Published+@StateObject+@ObservedObject+@ObservableObject+@Binding+$0$1
@ObservedObject,@State 和 @EnvironmentObject 有什么区别? SwiftUI Example
https://fandrian-rhamadiansyah.medium.com/swiftui-differences-between-observedobject-vs-stateobject-58eaf1a17fe Swift UI Property Wrappers
@State
struct ContentView: View {@State private var isRain = truevar body: some View {VStack {Image(systemName: isRain ? "cloud.rain.fill" : "sun.max.fill").resizable().frame(width: 100, height: 100)Text(isRain ? "我們淋著大雨不知何時才能放晴" : "太陽公公出來了,他對我呀笑呀笑")Button {isRain = Bool.random()} label: {Text("今天天氣如何 ?")}}}
}
struct 是赋值, class是引用
在struct 的计算属性(computed property)里,不允许改变成员变量
加上 @State 就可以改变了
参考:
用狀態設計 SwiftUI 畫面 — 認識 State property
sink
@Published + @StateObject + @ObservedObject
+ @ObservableObject
可以在继承 ObservableObject 的struct或class 的变量加上 @Published 的 property。
当变量改变,将会自动更新页面
class Baby: ObservableObject {@Published var age = 1
}
struct ContentView: View {@ObservedObject var cuteBaby = Baby()var body: some View {VStack {Text("\(cuteBaby.age) 岁").font(.largeTitle).padding().background(Capsule().foregroundColor(.yellow))Button(action: {cuteBaby.age += 1}, label: {Text("baby大一岁")})}}
}
改版一下,加个子view
struct BabyView: View {@StateObject var cuteBaby = Baby()var body: some View {VStack {AgeText(cuteBaby: cuteBaby)Button(action: {cuteBaby.age += 1}, label: {Text("baby大一岁")})}}
}struct AgeText: View {var cuteBaby: Babyvar body: some View {Text("\(cuteBaby.age) 岁").font(.largeTitle).padding().background(Capsule().foregroundColor(.yellow))}
}
再点击button,岁数不会变化
问题出在 AgeText 不知道它的页面需要更新,在 property cuteBaby 前加上 @ObservedObject,这样 cuteBaby 的 age 变化,页面才会更新
struct AgeText: View {@ObservedObject var cuteBaby: Babyvar body: some View {Text("\(cuteBaby.age) 岁").font(.largeTitle).padding().background(Capsule().foregroundColor(.yellow))}
}
另外如果 Baby 的类型为 struct, 则不会有这个问题
struct Baby {var age = 1
}
struct ContentView: View {@State var cuteBaby = Baby()var body: some View {VStack {Image("baby").resizable().scaledToFit()AgeText(cuteBaby: cuteBaby)Button(action: {cuteBaby.age += 1}, label: {Text("一暝大一寸")})}}
}
struct AgeText: View {var cuteBaby: Babyvar body: some View {Text("\(cuteBaby.age) 歲").font(.largeTitle).padding().background(Capsule().foregroundColor(.yellow))}
}
@Binding
SwiftUI 有很多控件都是可以 Binding 的控件,比如 Toggle,TextField,Slider 等。binding 的中文是绑定的意思,binding 将绑定 view & model, 它们之间将会实现双向沟通的功能:
- 操作控件,将会同步修改model内容
- 操作model里的对象,也会同步更新控件
跟vue 里的 v-bind v-model 比较像
import SwiftUIstruct Raining: View {@State private var isRain = truevar body: some View {VStack{Image(systemName: isRain ? "cloud.rain.fill" : "sun.max.fill").resizable().frame(width:100, height:100)Text(isRain ? "下雨了,快回家收衣服!" : "天晴了,拿衣服去晒晒!")Toggle(isOn: $isRain) {Text("今天下雨吗?")}}.padding()}
}struct Raining_Previews: PreviewProvider {static var previews: some View {Raining()}
}
修改一下代码,去掉 &
Toggle(isOn: isRain) {Text("今天下雨吗?")}
会提示错误
Cannot convert value 'isRain' of type 'Bool' to expected type 'Binding<Bool>', use wrapper instead
有binding的控件有:
- TextField
- Slider
- DatePicker
也可以自己产生binding
Toggle(isOn: Binding(get: { isRain }, set: { isRain = $0 }), label: {Text("今天下雨嗎?")
})
SwiftUI 綁定資料的 Binding 元件
$0$1
swift自动为闭包提供参数名缩写功能,可以直接通过$0和$1等来表示闭包中的第一个第二个参数,并且对应的参数类型会根据函数类型来进行判断。如下代码:
let numbers = [1,2,5,4,3,6,8,7]
sortNumbers = numbers.sorted(by: { (a, b) -> Bool inreturn a < b
})
print("numbers -" + "\(sortNumbers)")
- 使用$0,$1
let numbers = [1,2,5,4,3,6,8,7]
var sortNumbers = numbers.sorted(by: {$0 < $1})
print("numbers -" + "\(sortNumbers)")
参考
SwiftUI 產生 Binding 的各種方法
swift @State @Published+@StateObject+@ObservedObject+@ObservableObject+@Binding+$0$1相关推荐
- SwiftUI @State @Published @ObservedObject 深入理解和使用
1.SwiftUI 是Apple 新出面向未来.跨多端解决方案.声明式编程 SwiftUI最新版本 2.0 但是需要 IOS 14 支持,多数现在还用的是IOS 13 所以很多不完善的东西都用Swif ...
- SwiftUI之深入解析@StateObject、@ObservedObject和@EnvironmentObject的联系和区别
一.@State 属性包装器 ① 什么是 @State 属性包装器? 状态在任何现代应用程序中都是不可避免的,但在 SwiftUI 中,重要的是所有的视图都是它们状态的简单函数,我们不需要直接改变视图 ...
- SwfitUI之Published
// let objectWillChange = PassthroughSubject<Void, Never>()// var brain: CalculatorBrain = .le ...
- 5.8 设计模式之State(状态)—对象行为型模式
5.8 State(状态)-对象行为型模式 参考文章 意图 状态模式是一种行为设计模式, 改变一个对象的内部状态进而改变其行为. 问题及情景 状态模式与有限状态机的概念紧密相关. 其主要思想是程序在任 ...
- 以太坊EVM源码注释之State
以太坊EVM源码注释之State Ethereum State EVM在给定的状态下使用提供的上下文(Context)运行合约,计算有效的状态转换(智能合约代码执行的结果)来更新以太坊状态(Ether ...
- 游戏陪玩平台源码开发,关于本地通知推送实现的详细解析
游戏陪玩平台源码开发也是需要实现推送功能的,这样用户就能在第一时间了解平台消息以及好友发送的消息.这虽然只是一个小的方面,但却有着不容忽视的作用.今天我们主要了解一下利用系统的原生推送类结合工程实践如 ...
- 中改变了值但是数据没有刷新_SwiftUI数据流
SwiftUI 中的界面是严格数据驱动的:运行时界面的修改,只能通过修改数据来间接完成,而不是直接对界面进行修改操作. 数据处理的基本原则 Data Access as a Dependency:在 ...
- swiftui_使用SwiftUI在30分钟内制作一个应用
swiftui This post was first delivered as a live coding presentation at a Telstra Purple Back2Base ev ...
- SwiftUI3.0用户登录输入非空校验经典案例
SwiftUI3.0用户登录输入非空校验经典案例 在oc和swift里面,通过UITextFiled的代理方法,可以实施监听到用户输入的每个字符,使用正则表达式,进行判断,是否合法.在swiftUI通 ...
最新文章
- 004-CSS3动画类
- 在我的网站上开通了WebPart演示和下载列表。
- 老赖名下无财产,可以执行老赖子女名下的财产吗?
- python中读取指定的行和列_Python怎么获取excle中指定行和列的值?
- GitHub下载代码方法
- Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)
- 小学计算机属于数学与科学吗,我是计算机专业,想考小学信息技术教师资格证没有,那我是报科学还是...
- Spring MVC 全局异常处理(1) --HandlerExceptionResolver
- educoder 使用线程锁(lock)实现线程同步_Java8并发包源码分析:重入锁ReentrantLock和Condition实现原理...
- javaMail简介(一)
- asp.net c# 网页 导出excel 多表格 多个sheet
- ArcGIS:土地利用变化模式图绘制,土地利用转移矩阵
- hex文件、bin文件、axf文件的区别
- Latex表格排版大全 基于 IEEE双栏论文(设置单元格行列间距,自动换行设置)
- 怎样实现VLAN间通信,三种解决方案,一节课带你掌握
- 永恒之塔总是服务器未响应,《剑网3》《永恒之塔》怀旧服刚开上演“冲级热”,八月怀旧游戏集体搞事...
- access中本年度的四月一日_2014年3月计算机二级ACCESS上机试题及详解十二
- 数据挖掘里的“降维”----从五阶魔方的玩法思考
- 学习正则表达式 - 用 HTML 标记文本
- L2TP/IPSec 服务端安装
热门文章
- 不root怎么将FDex2反编译的dex文件拷出来
- speedoffice如何替换Word中的图片
- python axes函数_Python Matplotlib.axes.Axes.axvline()用法及代码示例
- Emiya 家今天的饭(CSP 2019 D2 T1)
- 足の痛いが続いて。。。
- 录制手机屏幕并且转换成GIF(手机,模拟器)
- 时序数据库TDengine基本概念和建模思路
- 安装程序未能打开日志文件_桌面安装工具日志记录错误的说明 - Office 365 | Microsoft Docs...
- 隐马尔可夫模型(HHM)学习笔记1
- 国内可以开展医疗器械管理体系(ISO13485)认证的机构名录