//
// Converter.swift
// TestUIKitApp
//
// Created by bob bob on 2021/3/10.
//
import Foundation
import SwiftUI
/*
@propertyWrapper 属性包装,可以理解为装饰器模式,比如 @State,@Binding,@ObjectBinding,@EnvironmentObject
1 init(initialValue:),wrappedValue 和 projectedValue 构成了一个 propertyWrapper 最重要的部分
不过 initialValue 这个参数名相对特殊:当它出现在 init 方法的第一个参数位置时,编译器将允许我们在声明的时候直接为 @State var value 进行赋值。
2 使用美元符号前缀 ($) 访问 ,其实访问的是 projectedValue 属性,不加$访问的是 wrappedValue 值。
3 在State 中,这个属性返回一个 Binding 类型的值,通过遵守BindingConvertible,State 暴露了修改其内部存储的方法,这也就是为什么传递 Binding 具有引用语义的原因。
下面是模仿@State写的一个美元转换装饰器
*/
@propertyWrapper
struct Converter1{
let from:String
let to:String
let rate:Double
var value:Double
var wrappedValue:String{
get{
"\(from)\(value)"
}
set{
value = Double(newValue) ?? -1
}
}
var projectedValue:String{
return "\(to)\(value * rate)"
}
init(initialValue:String,
from:String,
to:String,
rate:Double
) {
self.rate = rate
self.value = 0
self.from = from
self.to = to
self.wrappedValue = initialValue
}
}
struct TestWraper {
@State var myname = ""
@Converter1(initialValue: "100", from: "USD", to: "CNY", rate: 6.88)
var usd_cny
@Converter1(initialValue: "100", from: "CNY", to: "EUR", rate: 0.13)
var cny_eur
func test1(){
print("\(usd_cny)=\($usd_cny)")
print("\(cny_eur)=\($cny_eur)")
}
/*
USD100.0=CNY688.0
CNY100.0=EUR13.0
*/
}
ObservableObject
//
// ObServContentView.swift
// Calculator
//
// Created by bob bob on 2021/3/10.
// Copyright © 2021 OneV's Den. All rights reserved.
//
import SwiftUI
class Conect:ObservableObject{
var name:String
@Published var age:Int = 0
var num:Int{
willSet{
objectWillChange.send()
}
}
init(name:String,num:Int) {
self.name = name
self.num = num
for i in 1...10{
DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)) {
self.age += 1
}
}
}
}
struct ObServContentView: View {
@ObservedObject var john = Conect(name: "Bob",num: 0)
var body: some View {
Text("Age:\(john.age)")
Text("Num:\(john.num)")
Button(action: {
john.num += 1
}, label: {
Text("Button")
})
}
}
struct ObServContentView_Previews: PreviewProvider {
static var previews: some View {
ObServContentView()
}
}
EnvironmentObject
import SwiftUI
class User: ObservableObject {
@Published var name = "Bob"
}
struct MEditView:View {
@EnvironmentObject var user:User
var body: some View{
TextField("Name", text: $user.name)
}
}
struct NEditView:View {
@EnvironmentObject var user:User
var body: some View{
TextField("Name", text: $user.name)
}
}
struct EnvironmentContentView: View {
var user = User()
var num:Int = 0
var body: some View {
VStack{
//不要忘记环境中的实例,否则会崩溃
MEditView().environmentObject(user)
NEditView().environmentObject(user)
Button(action: {
user.name = user.name.appending("\(num)")
}, label: {
Text("NeditBtn")
})
}
}
}
struct EnvironmentContentView_Previews: PreviewProvider {
static var previews: some View {
EnvironmentContentView()
}
}
版权声明:本文为bobbob32原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。