Skip to content

Commit

Permalink
添加 SwiftUI 数据流内容
Browse files Browse the repository at this point in the history
  • Loading branch information
ming1016 committed May 6, 2024
1 parent 8e2deae commit f4a1527
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 1 deletion.
4 changes: 4 additions & 0 deletions SwiftPamphletApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
08522BED27CF7A0C005FF059 /* Keyboard(ap).md in Resources */ = {isa = PBXBuildFile; fileRef = 08522BEC27CF7A0C005FF059 /* Keyboard(ap).md */; };
085BB77427D22FCA00E8F69A /* SwiftUI动画(ap).md in Resources */ = {isa = PBXBuildFile; fileRef = 085BB77327D22FCA00E8F69A /* SwiftUI动画(ap).md */; };
085BB77627D22FE300E8F69A /* SwiftUI Canvas(ap).md in Resources */ = {isa = PBXBuildFile; fileRef = 085BB77527D22FE300E8F69A /* SwiftUI Canvas(ap).md */; };
08659BC72BE8FD84009B7C00 /* SwiftUI数据流(ap).md in Resources */ = {isa = PBXBuildFile; fileRef = 08659BC62BE8FD84009B7C00 /* SwiftUI数据流(ap).md */; };
0868D00B2BDD37280023C871 /* SMGitHub in Frameworks */ = {isa = PBXBuildFile; productRef = 0868D00A2BDD37280023C871 /* SMGitHub */; };
086A5F072744E88E00FECE02 /* SwiftPamphletAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086A5F062744E88E00FECE02 /* SwiftPamphletAppApp.swift */; };
086A5F0B2744E89100FECE02 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 086A5F0A2744E89100FECE02 /* Assets.xcassets */; };
Expand Down Expand Up @@ -354,6 +355,7 @@
08522BEC27CF7A0C005FF059 /* Keyboard(ap).md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "Keyboard(ap).md"; sourceTree = "<group>"; };
085BB77327D22FCA00E8F69A /* SwiftUI动画(ap).md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "SwiftUI动画(ap).md"; sourceTree = "<group>"; };
085BB77527D22FE300E8F69A /* SwiftUI Canvas(ap).md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "SwiftUI Canvas(ap).md"; sourceTree = "<group>"; };
08659BC62BE8FD84009B7C00 /* SwiftUI数据流(ap).md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "SwiftUI数据流(ap).md"; sourceTree = "<group>"; };
086A5F032744E88E00FECE02 /* 戴铭的开发小册子.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "戴铭的开发小册子.app"; sourceTree = BUILT_PRODUCTS_DIR; };
086A5F062744E88E00FECE02 /* SwiftPamphletAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftPamphletAppApp.swift; sourceTree = "<group>"; };
086A5F0A2744E89100FECE02 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -493,6 +495,7 @@
08449027279ECEA200B61353 /* 介绍 */,
0844902A279ECED300B61353 /* 视图组件使用 */,
08522BE727CF625B005FF059 /* 视觉 */,
08659BC62BE8FD84009B7C00 /* SwiftUI数据流(ap).md */,
);
path = SwiftUI;
sourceTree = "<group>";
Expand Down Expand Up @@ -1166,6 +1169,7 @@
08448F5B279EA84100B61353 /* macOS共享菜单(ap).md in Resources */,
0844900A279ECB8C00B61353 /* combineLatest(ap).md in Resources */,
08026C4D2869B3A600792EF1 /* Transferable(ap).md in Resources */,
08659BC72BE8FD84009B7C00 /* SwiftUI数据流(ap).md in Resources */,
08449011279ECC3E00B61353 /* Combine KVO(ap).md in Resources */,
08448FE2279EC7CF00B61353 /* Nil-coalescing(ap).md in Resources */,
08449002279ECB0500B61353 /* append(ap).md in Resources */,
Expand Down
3 changes: 2 additions & 1 deletion SwiftPamphletApp/Guide/GuideListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ final class GuideListModel {
L(t: "SwiftUI动画"),
L(t: "SwiftUI Canvas"),
L(t: "SF Symbol")
])
]),
L(t: "SwiftUI数据流")
]),
L(t: "Combine",sub: [
L(t: "介绍",sub: [
Expand Down
137 changes: 137 additions & 0 deletions SwiftPamphletApp/Resource/Guide/SwiftUI/SwiftUI数据流(ap).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@


## 属性

SwifUI 中的属性就是常量,不可变。

```swift
struct SomeView: View {
let saySomething = "你好世界"

var body: some View {
Text(saySomething)
}
}
```

## @State

当标记为 @State 的属性的值是可变的,当它改变时,视图会重新渲染。

```swift
struct ContentView: View {
@State private var isShowingAlert = false

var body: some View {
Button("Show Alert") {
isShowingAlert = true
}
.alert(isPresented: $isShowingAlert) {
Alert(title: Text("Hello, SwiftUI!"))
}
}
}
```

## @Binding

@Binding 是一个对其他视图的 @State 属性的引用。它允许我们在不拥有这个状态的情况下修改它。

```swift
struct ToggleSwitch: View {
@Binding var isOn: Bool

var body: some View {
Toggle(isOn: $isOn) {
Text("Toggle Switch")
}
}
}
```

## @Observable

下面的协议和属性包装在 iOS 17 后会被 `@Observable` 这个宏所替代了:

- `ObservableObject`
- `@ObservedObject`
- `@EnvironmentObject`
- `@Published`

如果你的程序是在 iOS 17 前写的,可以按照下面的步骤进行迁移:

- 第一步:删掉 ObservableObject 协议,添加 `@Observable`
- 第二步:删 Published 属性
- 第三步:给不需要观察的属性添加 `@ObservationIgnored`
- 第四步:将 `@ObservedObject` 替换成 `@State`
- 第五步:将 `@Binding` 改成 `@Bindable`
- 第六步:将 environmentObject 换成 environment


## @Environment

@Environment 是一个从环境中获取系统设置或状态的属性。

```swift
struct ContentView: View {
@Environment(\.layoutDirection) var layoutDirection

var body: some View {
if layoutDirection == .leftToRight {
Text("Left to Right layout")
} else {
Text("Right to Left layout")
}
}
}
```

Observable 用于 Environment 的方式,举个例子。

有个 Observable 类。

```swift
import Observation

@Observable class Cat {
var isOrange: Bool = false
}
```

使用 environment 修饰符

```swift
SomeView()
.environment(Cat())
```

使用键路径声明一个 `Environment` 属性

```swift
struct SomeView: View {
@Environment(Cat.self) private var cat

var body: some View {
@Bindable var catBindable = cat
Toggle(isOn: $catBindable.isOrange, label: {
Text("是不是橘猫")
})
}
}
```


## @AppStorage

@AppStorage 是一个用于存储用户设置的简单键值存储。当存储的值改变时,视图会重新渲染。

```swift
struct ContentView: View {
@AppStorage("username") var username: String = "Guest"

var body: some View {
Text("Hello, \(username)!")
}
}
```

0 comments on commit f4a1527

Please sign in to comment.