SwiftUI:@State 变量在其值更改时不更新视图(在同一视图中)
SwiftUI: @State variable does not update View when its value changes (within same View)
我是 SwiftUI 的新手。也许我不完全理解 @State 注释变量的工作原理。据我所知,当你更新它们的值时,如果它们在同一个视图中,屏幕也会更新(在本例中是屏幕的背景颜色)。我想我完全按照视频教程 (SwiftUI Basics Tutorial) 进行了操作,但我仍然没有让我的代码工作。顺便说一句,如果值得一提的话,我使用的是 Xcode 版本 13.2.1。在我的 ContentView.swift
中,这是我拥有的:
//
// ContentView.swift
//
import SwiftUI
struct ContentView: View {
@State private var isNight = false //Variable to be changed when pressing the button
var body: some View {
ZStack {
//The BackgroundView color should change when pressing the button
BackgroundView(topColor: isNight ? .black : .blue,
bottomColor: isNight ? .gray : Color("lightBlue"))
VStack{
CityTextView(cityName: "Cupertino, CA")
MainWeatherStatusView(imageName: "cloud.sun.rain.fill",
temperature: 72)
HStack(spacing: 0){
WeatherView(dayOfWeek: "TUE",
imageName: "cloud.sun.fill",
temperature: 74)
WeatherView(dayOfWeek: "WED",
imageName: "sun.max.fill",
temperature: 30)
WeatherView(dayOfWeek: "THU",
imageName: "wind.snow",
temperature: 5)
WeatherView(dayOfWeek: "FRI",
imageName: "sunset.fill",
temperature: 60)
WeatherView(dayOfWeek: "SAT",
imageName: "snow",
temperature: 74)
}
Button{
isNight.toggle() //Changing this should update my View, right?
} label: {
WeatherButton(title: "Change Day Time",
textColor: .blue,
backgroundColor: .white)
}
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct WeatherView: View {
var dayOfWeek: String
var imageName: String
var temperature: Int
var body: some View {
VStack{
Text(dayOfWeek)
.font(.system(size: 15, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
Text("\(temperature)°")
.font(.system(size: 30, weight: .medium))
.foregroundColor(.white)
Spacer()
}
}
}
struct BackgroundView: View {
var topColor: Color
var bottomColor: Color
var body: some View {
LinearGradient(gradient: Gradient(colors: [.blue, Color("lightBlue")]), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
}
}
struct CityTextView: View {
var cityName: String
var body: some View {
Text(cityName)
.font(.system(size: 32, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
}
}
struct MainWeatherStatusView: View {
var imageName: String
var temperature: Int
var body: some View {
VStack(spacing: 8){
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 180, height: 180)
Text("\(temperature)°")
.font(.system(size: 70, weight: .medium))
.foregroundColor(.white)
}
}
}
如果您想复制粘贴代码并删除图标,这里是没有图标的代码:
//
// ContentView.swift
//
import SwiftUI
struct ContentView: View {
@State private var isNight = false //VARIABLE TO BE CHANGED WHEN PRESSING BUTTON
var body: some View {
ZStack {
//The BackgroundView color should change when pressing the button
BackgroundView(topColor: isNight ? .black : .blue,
bottomColor: isNight ? .gray : Color("lightBlue"))
VStack{
CityTextView(cityName: "Cupertino, CA")
Button{
isNight.toggle() //CHANGING THIS SHOULD UPDATE MY VIEW, RIGHT?
} label: {
WeatherButton(title: "Change Day Time",
textColor: .blue,
backgroundColor: .white)
}
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct WeatherView: View {
var dayOfWeek: String
var imageName: String
var temperature: Int
var body: some View {
VStack{
Text(dayOfWeek)
.font(.system(size: 15, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
Text("\(temperature)°")
.font(.system(size: 30, weight: .medium))
.foregroundColor(.white)
Spacer()
}
}
}
struct BackgroundView: View {
var topColor: Color
var bottomColor: Color
var body: some View {
LinearGradient(gradient: Gradient(colors: [.blue, Color("lightBlue")]), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
}
}
struct CityTextView: View {
var cityName: String
var body: some View {
Text(cityName)
.font(.system(size: 32, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
}
}
struct MainWeatherStatusView: View {
var imageName: String
var temperature: Int
var body: some View {
VStack(spacing: 8){
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 180, height: 180)
Text("\(temperature)°")
.font(.system(size: 70, weight: .medium))
.foregroundColor(.white)
}
}
}
在您当前的 BackgroundView
代码中,虽然您有 topColor
和 bottomColor
参数,但您实际上并没有 使用 它们看法。您可能希望将它们包含在渐变中:
struct BackgroundView: View {
var topColor: Color
var bottomColor: Color
var body: some View {
LinearGradient(gradient: Gradient(colors: [topColor, bottomColor]), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
}
}
此外,请确保您的资产目录中有自定义颜色(如 Color("lightBlue")
)。
我是 SwiftUI 的新手。也许我不完全理解 @State 注释变量的工作原理。据我所知,当你更新它们的值时,如果它们在同一个视图中,屏幕也会更新(在本例中是屏幕的背景颜色)。我想我完全按照视频教程 (SwiftUI Basics Tutorial) 进行了操作,但我仍然没有让我的代码工作。顺便说一句,如果值得一提的话,我使用的是 Xcode 版本 13.2.1。在我的 ContentView.swift
中,这是我拥有的:
//
// ContentView.swift
//
import SwiftUI
struct ContentView: View {
@State private var isNight = false //Variable to be changed when pressing the button
var body: some View {
ZStack {
//The BackgroundView color should change when pressing the button
BackgroundView(topColor: isNight ? .black : .blue,
bottomColor: isNight ? .gray : Color("lightBlue"))
VStack{
CityTextView(cityName: "Cupertino, CA")
MainWeatherStatusView(imageName: "cloud.sun.rain.fill",
temperature: 72)
HStack(spacing: 0){
WeatherView(dayOfWeek: "TUE",
imageName: "cloud.sun.fill",
temperature: 74)
WeatherView(dayOfWeek: "WED",
imageName: "sun.max.fill",
temperature: 30)
WeatherView(dayOfWeek: "THU",
imageName: "wind.snow",
temperature: 5)
WeatherView(dayOfWeek: "FRI",
imageName: "sunset.fill",
temperature: 60)
WeatherView(dayOfWeek: "SAT",
imageName: "snow",
temperature: 74)
}
Button{
isNight.toggle() //Changing this should update my View, right?
} label: {
WeatherButton(title: "Change Day Time",
textColor: .blue,
backgroundColor: .white)
}
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct WeatherView: View {
var dayOfWeek: String
var imageName: String
var temperature: Int
var body: some View {
VStack{
Text(dayOfWeek)
.font(.system(size: 15, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
Text("\(temperature)°")
.font(.system(size: 30, weight: .medium))
.foregroundColor(.white)
Spacer()
}
}
}
struct BackgroundView: View {
var topColor: Color
var bottomColor: Color
var body: some View {
LinearGradient(gradient: Gradient(colors: [.blue, Color("lightBlue")]), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
}
}
struct CityTextView: View {
var cityName: String
var body: some View {
Text(cityName)
.font(.system(size: 32, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
}
}
struct MainWeatherStatusView: View {
var imageName: String
var temperature: Int
var body: some View {
VStack(spacing: 8){
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 180, height: 180)
Text("\(temperature)°")
.font(.system(size: 70, weight: .medium))
.foregroundColor(.white)
}
}
}
如果您想复制粘贴代码并删除图标,这里是没有图标的代码:
//
// ContentView.swift
//
import SwiftUI
struct ContentView: View {
@State private var isNight = false //VARIABLE TO BE CHANGED WHEN PRESSING BUTTON
var body: some View {
ZStack {
//The BackgroundView color should change when pressing the button
BackgroundView(topColor: isNight ? .black : .blue,
bottomColor: isNight ? .gray : Color("lightBlue"))
VStack{
CityTextView(cityName: "Cupertino, CA")
Button{
isNight.toggle() //CHANGING THIS SHOULD UPDATE MY VIEW, RIGHT?
} label: {
WeatherButton(title: "Change Day Time",
textColor: .blue,
backgroundColor: .white)
}
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct WeatherView: View {
var dayOfWeek: String
var imageName: String
var temperature: Int
var body: some View {
VStack{
Text(dayOfWeek)
.font(.system(size: 15, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
Text("\(temperature)°")
.font(.system(size: 30, weight: .medium))
.foregroundColor(.white)
Spacer()
}
}
}
struct BackgroundView: View {
var topColor: Color
var bottomColor: Color
var body: some View {
LinearGradient(gradient: Gradient(colors: [.blue, Color("lightBlue")]), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
}
}
struct CityTextView: View {
var cityName: String
var body: some View {
Text(cityName)
.font(.system(size: 32, weight: .medium, design: .default))
.foregroundColor(.white)
.padding()
}
}
struct MainWeatherStatusView: View {
var imageName: String
var temperature: Int
var body: some View {
VStack(spacing: 8){
Image(systemName: imageName)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 180, height: 180)
Text("\(temperature)°")
.font(.system(size: 70, weight: .medium))
.foregroundColor(.white)
}
}
}
在您当前的 BackgroundView
代码中,虽然您有 topColor
和 bottomColor
参数,但您实际上并没有 使用 它们看法。您可能希望将它们包含在渐变中:
struct BackgroundView: View {
var topColor: Color
var bottomColor: Color
var body: some View {
LinearGradient(gradient: Gradient(colors: [topColor, bottomColor]), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
}
}
此外,请确保您的资产目录中有自定义颜色(如 Color("lightBlue")
)。