如何使用String类型状态变量实现按钮点击切换图片?
解决方案
核心思路
直接利用API返回的type字符串字段判断状态,无需额外的Bool类型变量。当type为"success"时显示填充红心,其他情况显示灰色空心心。
代码修改步骤
- 修正ViewModel的API响应处理
你当前的addWishlist类中,解码后仅赋值了records,未给responses赋值,导致视图无法获取type字段。补充赋值逻辑:
class addWishlist: ObservableObject { @Published private(set) var records: addRecord? @Published private(set) var responses: add? func loadData() { let url = URL(string: addwishlist_URL) guard let requestUrl = url else { fatalError() } var request = URLRequest(url: requestUrl) request.httpMethod = "POST" let postString = "roomid=xxxxxxxxxxx&emailid=xxxxxxxxxxxx" request.httpBody = postString.data(using: String.Encoding.utf8); let task = URLSession.shared.dataTask(with: request) { (data, response, error) in do { if let todoData = data { let decodedData = try JSONDecoder().decode(add.self, from: todoData) DispatchQueue.main.async { self.records = decodedData.record self.responses = decodedData // 补充赋值完整响应 print(decodedData.record) print(decodedData.type) } } else { print("No data") } } catch { print(error) } } task.resume() } }
- 简化视图代码,移除多余状态变量
删除无用的type和typeClicked状态变量,直接通过viewModel.responses?.type判断显示状态:
struct YourView: View { @StateObject var viewModel = addWishlist() var body: some View { VStack{ HStack { Image("resort1") Spacer() Button { viewModel.loadData() // 点击触发API请求 } label: { Image(systemName: viewModel.responses?.type == "success" ? "heart.fill" : "heart") .font(.system(size: 25)) .foregroundColor(viewModel.responses?.type == "success" ? .red : Color(uiColor: .systemGray3)) } } .padding() } } }
- 保持结构体定义不变
你的add和addRecord结构体无需修改,确保type字段能正确解码即可:
struct add: Codable { var type: String let record: addRecord } struct addRecord: Codable { // 根据API返回字段补充对应属性 }
说明
- 点击按钮时触发API请求,请求完成后ViewModel的
responses更新,视图会自动刷新状态。 - 当API返回的
type为"success"时,按钮显示红色填充红心;其他值(或未发起请求时)显示灰色空心心。
内容的提问来源于stack exchange,提问作者user19179931
相关产品推荐
相关产品推荐

