更新属性包装器,例如@StateObject,会影响不使用该属性的其他视图渲染
当使用与视图更新关联的不同属性包装器时,一个位置的更改会影响不使用该属性的视图的渲染。
struct ContentView: View {
@StateObject var viewModel = MyViewModel()
@State var thirdTitle = "thirdTitle"
var body: some View {
VStack {
Text(viewModel.firstTitle)
.background(.random)
Text(viewModel.secondTitle)
.background(.random)
Text(thirdTitle)
.background(.random)
Button("Change First Title") {
viewModel.chageFirstTitle()
}
}
}
}
class MyViewModel: ObservableObject {
@Published var firstTitle = "firstTitle"
@Published var secondTitle = "secondTitle"
func chageFirstTitle() {
firstTitle = "hello world"
}
}
我了解text
公开viewModel.secondtitle
重新渲染是因为@StateObject varviewModel = myViewModel()
依赖关系在更改`viewModel.firsttitle时更改。
但是,我不知道为什么文本
使用@State var trixtitle =“ thixttitle”
也被重新渲染。在wwdc21 session demystife swiftui ,我看到了该视图仅在根据依赖关系图更新相关的依赖项时重新渲染。但是,即使thixtetle
与更改viewmodel
的更改无关改变了。
更令人困惑的是,如果我将第三个文本
分开为单独的视图(thirdview
),然后使用@binding接收
,背景颜色不会更改,因为当时它没有重新渲染。thixttitle
struct ContentView: View {
@StateObject var viewModel = MyViewModel()
@State var thirdTitle = "thirdTitle"
var body: some View {
VStack {
Text(viewModel.firstTitle)
.background(.random)
Text(viewModel.secondTitle)
.background(.random)
ThirdView(text: $thirdTitle)
.background(.random)
Button("Change First Title") {
viewModel.chageFirstTitle()
}
}
}
}
struct ThirdView: View {
@Binding var text: String
var body: some View {
Text(text)
.background(.random)
}
}
关于我解释的情况,您能帮我了解视图的渲染条件吗?
When using different property wrappers associated with view updates, changes in one place affect rendering of views that do not use that property.
struct ContentView: View {
@StateObject var viewModel = MyViewModel()
@State var thirdTitle = "thirdTitle"
var body: some View {
VStack {
Text(viewModel.firstTitle)
.background(.random)
Text(viewModel.secondTitle)
.background(.random)
Text(thirdTitle)
.background(.random)
Button("Change First Title") {
viewModel.chageFirstTitle()
}
}
}
}
class MyViewModel: ObservableObject {
@Published var firstTitle = "firstTitle"
@Published var secondTitle = "secondTitle"
func chageFirstTitle() {
firstTitle = "hello world"
}
}
I understand that the reason why the Text
exposing the viewModel.secondTitle
is re-rendered is because the @StateObject varviewModel = MyViewModel()
dependency changed when the `viewModel.firstTitle changed.
However, I don't know why Text
using @State var thirdTitle = "thirdTitle"
is re-rendered too. In WWDC21 session Demystify SwiftUI, I saw that the view is re-rendered only when the related dependency is updated according to the dependency graph. But, even though the thirdTitle
is irrelevant to the change of the viewModel
, third Text
using that dependency is re-rendered and the background color is changed.
What's even more confusing is that if I seperate the third Text
into a separate view ( ThirdView
) and receive the thirdTitle
using @Binding
, the background color does not change because it is not re-rendering at that time.
struct ContentView: View {
@StateObject var viewModel = MyViewModel()
@State var thirdTitle = "thirdTitle"
var body: some View {
VStack {
Text(viewModel.firstTitle)
.background(.random)
Text(viewModel.secondTitle)
.background(.random)
ThirdView(text: $thirdTitle)
.background(.random)
Button("Change First Title") {
viewModel.chageFirstTitle()
}
}
}
}
struct ThirdView: View {
@Binding var text: String
var body: some View {
Text(text)
.background(.random)
}
}
Regarding the situation I explained, could you help me to understand the rendering conditions of the view?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要渲染swiftui调用
body
视图的属性(它是可计算的,即在呼叫上完全执行)。每当更改任何视图依赖项(即动态属性)时,都会执行此调用。因此,
viewModel.ChageFirstTitle()
更改contentView
和content> contentview.body
的依赖关系,并呈现其中的每个原始性。也创建了
,但就其依赖关系而言而言,其body
未调用,因此不重新渲染内容。To render SwiftUI calls
body
property of a view (it is computable, i.e. executes completely on call). This call is performed whenever any view dependency, i.e. dynamic property, is changed.So,
viewModel.chageFirstTitle()
changes dependency forContentView
andContentView.body
is called and every primitive in it is rendered.ThirdView
also created but as far as its dependency is not changed, itsbody
is not called, so content is not re-rendered.这里有一些错误。我们不会在SwiftUI中使用查看模型对象进行查看数据,这样做是相当低效率的/错误的。相反,将带有
@State
突变弹性的结构使用。将参数传递给子视图,作为让读取访问的让@binding
仅在您需要写入访问时才是。在渲染方面,首先仅在 的情况然后有任何差异,然后SwiftUi代表您添加/删除/更新实际的Uikit Uiviews,然后由这些Uiview的实际渲染,例如drawRect
,由Coregraphics。Combine的
observableObject
通常仅在需要使用组合时使用,例如使用combineLatest
与多个发布者或用于store> Store
对象保持模型结构阵列在@published
属性中,这些属性与视图的寿命没有@state
。您的用例看起来不像observableObject
的有效用途。A few things wrong here. We don't use view model objects in SwiftUI for view data, it's quite inefficient/buggy to do so. Instead, use a struct with mutating funcs with an
@State
. Pass in params to sub-Views as lets for read access,@Binding
is only when you need write access. In terms of rendering, first of allbody
is only called if the let property is different from the last time the sub-View is init, then it diffs the body from the last time it was called, if there are any differences then SwiftUI adds/removes/updates actual UIKit UIViews on your behalf, then actual rendering of those UIViews, e.g.drawRect
, is done by CoreGraphics.Combine's
ObservableObject
is usually only used when needing to use Combine, e.g. usingcombineLatest
with multiple publishers or for aStore
object to hold the model struct arrays in@Published
properties that are not tied to a View's lifetime like@State
. Your use case doesn't look like a valid use ofObservableObject
.