Цвет фона SecondView
не меняется должным образом, когда я нажимаю кнопку, однако случайное число в ThirdView
обновляется каждый раз. Почему так происходит, и SecondView, и ThirdView не имеют явной зависимости от состояния, думаю, их обоих пересоздавать не стоит.
Apple Docs: Когда значение @State изменяется, SwiftUI обновляет части иерархии представлений, которые зависят от значения.
struct ParentView: View {
@State var counter: Int = 0
var body: some View {
VStack {
Text("ContentView \(counter)")
SecondView()
ThirdView()
Button {
counter += 1
} label: {
Text("Go!")
}
}
}
}
struct SecondView: View {
var body: some View {
Text("SecondView")
.background(.debug)
}
}
struct ThirdView: View {
let randomNumber = Int.random(in: 1...100)
var body: some View {
Text("Random Number: \(randomNumber)")
}
}
public extension ShapeStyle where Self == Color {
static var debug: Color {
Color(
red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1)
)
}
}
Если вы удалите Text("ContentView \(counter)")
, ThirdView перестанет обновляться.
Теперь вы понимаете, почему ThirdView обновляется? Вам требуется регенерация всего VStack, поэтому SecondView и ThirdView являются кандидатами на создание экземпляров заново; это будут совершенно новые представления, поэтому новый экземпляр ThirdView получает новое случайное число в качестве свойства randomNumber
. (randomNumber
не может измениться; это константа let
!)
Что касается SecondView, его цвет определяется вычисляемой переменной. Ему все равно, что произойдет с ParentView. Таким образом, SecondView не требует регенерации, а цвет фона SecondView остается неизменным — до тех пор, пока вы снова не запустите все приложение.
Чтобы SecondView действовал как ThirdView, присвойте ему свойство let
, которое будет случайным цветом, как и ThirdView:
struct SecondView: View {
let debug = Color(
red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1)
)
var body: some View {
Text("SecondView")
.background(debug)
}
}
Или сыграйте в другую сторону: замените let
в ThirdView на @State var
. Теперь ThirdView больше не обновляется при нажатии кнопки.
struct ThirdView: View {
@State var randomNumber = Int.random(in: 1...100)
var body: some View {
Text("Random Number: \(randomNumber)")
}
}