SwiftUI如何基于获取的数据更改视图的背景颜色?

如何解决SwiftUI如何基于获取的数据更改视图的背景颜色?

我正在SwiftUI上开发一个基本的天气应用程序,该应用程序可以根据天气状况动态更改颜色。一切工作正常,但是我无法将通过JSON解析的OpenWeatherMap图标数据发送到我的View。看来它没有将从另一个Swift文件发送的信息分配给我声明的变量。我对普通的Swift有一定的经验,但是SwiftUI的概念肯定是不熟悉的。

这是我下面的ContentView.swift。

   import SwiftUI

struct ContentView: View {
    @State private var selected = 0
    @ObservedObject var weather = CurrentWeatherViewModel()
    @State var city : String = ""
    private var height : CGFloat = UIScreen.main.bounds.height
        var body: some View {
            VStack{
                HStack{
                    TextField("Enter your city",text: $city){
                    self.weather.fetchmetric(self.city)
                    }.padding(.horizontal)
                    
                }
                    GeometryReader{ gr in
                        CurrentWeather(weather: self.weather.current,height: self.selected == 0 ? gr.size.height : (gr.size.height*0.75)).frame(width: 375.0,height: 770).modifier(currentViewModifier()).animation(.easeInOut(duration: 0.5))
                    }.edgesIgnoringSafeArea(.all)
                    
            }.frame(width: 375,height: 735,alignment: .center)
            
        
            
        }
    }

这是我的CurrentWeather.swift文件。 @State颜色变量是我需要更改的变量。

    import SwiftUI
import UIKit

struct CurrentWeather: View {
    // Added color themes for potential weather scenarios
    let bgColors = [
        "Clear":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.6544341662,green: 0.9271220419,blue: 0.9764705896,alpha: 1)),Color( #colorLiteral(red: 0.2392156869,green: 0.6745098233,blue: 0.9686274529,alpha: 1))]),startPoint: .top,endPoint: .bottom),"Sunny":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.9764705896,green: 0.850980401,blue: 0.5490196347,Color( #colorLiteral(red: 0.9529411793,green: 0.8685067713,blue: 0.1800223484,"Partly cloudy":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.5644291786,green: 0.6156922265,blue: 0.8125274491,Color( #colorLiteral(red: 0.3611070699,green: 0.3893437324,blue: 0.5149981027,"Cloudy":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.5088317674,green: 0.5486197199,blue: 0.7256778298,Color( #colorLiteral(red: 0.3843137255,green: 0.4117647059,blue: 0.5450980392,"Broken clouds":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.4714559888,green: 0.41813849,blue: 0.4877657043,Color( #colorLiteral(red: 0.3823538819,green: 0.3384427864,blue: 0.3941545051,"Mist":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.8536048541,green: 0.8154317929,blue: 0.6934956985,Color( #colorLiteral(red: 0.5,green: 0.3992742327,blue: 0.3267588525,"Patchy rain possible":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.422871705,green: 0.486337462,blue: 0.7241632297,Color(#colorLiteral(red: 0.3826735404,green: 0.4012053775,blue: 0.9529411793,"Patchy snow possible":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.8229460361,green: 0.8420813229,Color( #colorLiteral(red: 0.6424972056,green: 0.9015246284,"Patchy sleet possible":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.9764705896,green: 0.7979655136,blue: 0.9493740175,Color( #colorLiteral(red: 0.6843526756,green: 0.7806652456,"Patchy freezing drizzle possible":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.6207757569,green: 0.9686274529,blue: 0.9110963382,Color( #colorLiteral(red: 0.4745098054,green: 0.8392156959,"Thundery outbreaks possible":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.3647058904,green: 0.06666667014,Color( #colorLiteral(red: 0.1764705926,green: 0.01176470611,blue: 0.5607843399,"Blowing snow":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.1764705926,Color( #colorLiteral(red: 0.09019608051,green: 0,blue: 0.3019607961,"Thunderstorm":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.9551106616,green: 0.9764705896,blue: 0.9351792135,Color( #colorLiteral(red: 0.6891936611,green: 0.7095901305,"Fog":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.6324083141,green: 0.8039215803,blue: 0.7850640474,Color( #colorLiteral(red: 0.4545597353,green: 0.393878495,blue: 0.5369011739,"Freezing fog":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.8039215803,blue: 0.8039215803,"Patchy light drizzle":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.5892893535,green: 0.7170531098,"Light rain":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.2392156869,Color( #colorLiteral(red: 0.2854045624,green: 0.4267300284,blue: 0.6992385787,"Moderate rain":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.3437546921,green: 0.6157113381,blue: 0.7179171954,Color( #colorLiteral(red: 0.4118283819,green: 0.5814552154,blue: 0.6975531409,"Heavy rain":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.1764705926,green: 0.4980392158,blue: 0.7568627596,Color( #colorLiteral(red: 0.1596036421,blue: 0.5802268401,"Light freezing rain":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.7433765433,green: 0.9529411793,blue: 0.8886958889,Color( #colorLiteral(red: 0.4561494407,green: 0.6342332627,"Heavy rain at times":LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.1764705926,"defaultStatus":LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 0.9372549057,green: 0.3490196168,blue: 0.1921568662,Color(#colorLiteral(red: 0.9686274529,green: 0.78039217,blue: 0.3450980484,endPoint: .bottom)
    ]
    
    var weather : Weather?
    var height : CGFloat = 0
    
   @State var color : String = "defaultStatus"
    
    var body: some View {
        NavigationView{
        VStack(alignment: .center,spacing: 10) {
            Image(weather?.weather.last?.icon ?? "01d")
                .resizable()
                .frame(width: 130,height: 130)
                .aspectRatio(contentMode: .fit)
            Text("Today in \(weather?.name ?? "Unknown")")
                .font(.title)
                .foregroundColor(.white)
            .bold()
            .padding()
            HStack{
                Text("\(weather?.main.temp ?? 0)°")
                    .foregroundColor(.white)
                    .fontWeight(.heavy)
                    .font(.system(size: 50))
               
            }
            Text("\(weather?.weather.last?.description ?? "Unknown")")
                .foregroundColor(.white)
                .font(.body)
            
        }.frame(width: height,height: height)
            .background(bgColors[color])
            
        .navigationBarItems(trailing:
                                NavigationLink(destination: Settings()) {
                                    Image(systemName: "gear").imageScale(.large).accentColor(.black)
                            })
        }.onAppear {} // Code Execution at startup
    }
}

struct currentViewModifier : ViewModifier{
    private var radius : CGFloat = 20
    private var xAxis : CGFloat = 20
    private var yAxis : CGFloat = 20
    
    func body(content: Content) -> some View {
        content
            .cornerRadius(radius)
            
            .opacity(1.0)
        
    }
}

这是我的WeatherModel.swift文件,其中有执行提取的功能和使代码运行的background()函数。

    import Foundation
import Combine

final class CurrentWeatherViewModel : ObservableObject{
    @Published var current : Weather?
    
    init() {
        DispatchQueue.main.async {
            //if Settings().selected == 0{
                self.fetchmetric()
            //}
           // else{
                self.fetchimperial()
           // }
        }
    }
}

// fetch functions for metric and imperial and set color at the home screen

extension CurrentWeatherViewModel {
    func fetchmetric(_ city : String = "london"){
        let icon = current?.weather.last?.icon
        API.fetchCurrentmetricWeather(by: city) {
            // Work In Progress
            
            self.current = $0
            CurrentWeather().color = self.backgroundColor(code: icon ?? "aaa")
        }
    }
    
    func fetchimperial(_ city : String = "london"){
        API.fetchCurrentimperialWeather(by: city) {
            self.current = $0
            
        }
    }
    func backgroundColor(code : String) -> String {
        
        switch code {
            case "01d":
                return "Clear"
            case "02d":
                return "Partly cloudy"
            case "02n":
                return "Partly cloudy"
            case "03d":
                return "Cloudy"
            case "03n":
                return "Cloudy"
            case "04d":
                return "Broken clouds"
            case "04n":
                return "Broken clouds"
            case "09d":
                return "Moderate Rain"
            case "09n":
                return "Heavy rain"
            case "10d":
                return "Moderate Rain"
            case "10n":
                return "Heavy rain"
            case "11d":
                return "Thunderstorm"
            case "11n":
                return "Thunderstorm"
            case "13d":
                return "Snow"
            case "13n":
                return "Snow"
            case "50d":
                return "Mist"
            case "50n":
                return "Mist"
            default:
                return "defaultStatus"
            }
        }
        
}

我的问题是,我不知道它没有将图标数据发送到CurrentWeather颜色变量吗?我必须说我不熟悉@State变量并尝试学习SwiftUI。

赞赏代码上的所有输入内容。

解决方法

表达式 CurrentWeather().color = self.backgroundColor(code: icon ?? "aaa")毫无意义,因为修改了本地创建的值(CurrentWeather()创建了结构值)。

相反,您需要在视图模型中为颜色创建发布的属性并使用它,例如

final class CurrentWeatherViewModel : ObservableObject{
    @Published var current : Weather?
    @Publisehd var color: String = "aaa"

然后将其更新为

API.fetchCurrentmetricWeather(by: city) { weather in
    // Work In Progress
    
    DispatchQueue.main.async { // update published on main queue !!!
       self.current = weather
       self.color = self.backgroundColor(code: icon ?? "aaa")
    }
}

然后在类似的视图中使用它

    }.frame(width: height,height: height)
        .background(bgColors[self.weather?.color ?? "defaultStatus"])

不需要本地视图@State var color

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res