This is the sixth day of my participation in the August More text Challenge. For details, see:August is more challenging
above
- SwiftUI actual Combat – Copy wechat App (1)
- SwiftUI Actual Combat – Copy wechat App (2)
- SwiftUI Actual Combat – Copy wechat App (3)
- SwiftUI Actual Combat – Copy wechat App (4)
- SwiftUI Actual Combat – Copy wechat App (5)
1. Cross-layer data sharing
As mentioned in the previous chapter, the parent modifies the variable with @state, and the child modifies the variable with @binding. By passing the parameter, the variable can be shared, that is, whether the parent or the child changes the value of the variable, each other will be aware of it.
Graph LR parent - > share | | variable child - > share | | variable
However, there is also a case where data is referenced in multiple views that are not parent and want to share the variable.
Shared graph TD the View1 = = > | | variable View3 = = > share | | variable View2.1 - > View3 View2.2 - > View3 the View1 - > View2.1 the View1 - > View2.2
View1 and View3 both hold this variable, but not at the parent level.
2. Combine framework
SwiftUI provides a framework, Combine, which uses the MVVM design pattern.
MVVM is short for Model-view-ViewModel.
Model
This refers to shared variables.View
That’s the view layer, same as aboveView1,View2,View3
.ViewModel
Similar to a hub, putModel
andView
Link it up.
graph LR
subgraph ViewModel
Model
end
subgraph View
ViewModel
end
ViewModel
Hold a variableModel
By some means (more on that later) willModel
Becomes a shared variable.View
The introduction ofViewModel
Class,ViewModel
operationModel
, such as adding, deleting, and other operations, other referencesView
Will be notified.
Three, the ModelView
Start by creating a ModelView class. Xcode creates a Swift File instead of a SwiftUI View
import Foundation
class AnimalViewModel{}Copy the code
Note: The ViewModel must be a class, not a struct.
Then implement the ObservableObject protocol, informing SwiftUI that this is a ViewModel class.
Fourth, the Model
Next, create the Model in ViewModel.
class AnimalViewModel: ObservableObject{
var animals: [String] =[]}Copy the code
Model is not a data type. It can be an array or any other type, even if it is a Bool variable.
Similarly, the Model needs to prove itself, so use the @publish annotation.
@Published var animals: [String] = []
Copy the code
Fifth, the View
Reference the ViewModel in the View.
Create two views :TVView and PCView, import ViewModel respectively, and display the same List.
Like TVView, PCView is the same as TVView.
struct TVView: View {
var model: AnimalViewModel
var body: some View {
List{
Text("TVView")
Button(action: {
model.animals.append("cat")
}, label: {
Text("addAnimal")})ForEach(0..<model.animals.count, id: \.self){index in
Text(model.animals[index])
}
}
}
}
Copy the code
As in the previous two steps, the View also needs to notify SwiftUI of its reference to the ViewModel. Modify the ViewModel with @environmentobject.
@EnvironmentObject var model: AnimalViewModel
Copy the code
Vi.ViewModel
The hierarchy
Finally, while the ViewModel is tagged with the @Environmentobject annotation, SwiftUI is not informed where to create the ViewModel, that is, on what View hierarchy to create the ViewModel on.
Graph TD subgraph View1 create ViewModel View1 --> View2.1 View1 --> View2.2 View2.1 --> View3.2 end View2.2 --> View3.3 --> View3.4 end
As shown above,
If you create a ViewModel at the View1 level, the Model can be shared across all levels View1, View2, and View3.
If created at the View2.1 level, the Model can only be shared in View2.1, View3.1, and View3.2.
So how do you create that?
In the WeChatModel project, the ContentView is the top View. You just need to find where the ContentView was created.
The following figure
To be clear, although both are EnvironmentObject, one uses the @environmentobject annotation to tag the ViewModel in the View and the other specifies the scope of influence of the ViewModel.
All we need to do is specify the scope of influence, and it’s up to SwiftUI to decide when to create it.
The final result is as follows:
Attached: Code address
Gitee.com/dkwingcn/we…