英文:
Change the button's image on click with State variable as String?
问题
以下是代码部分的翻译:
We can change the image with the help of a button using state variable as Boolean. But how do we achieve that using a string variable?
For Example:
If State variable is a bool:-
Image(systemName: self.typeClicked ? "heart.fill" : "heart.fill")
如果状态变量是布尔值,那么 " self.typeClicked ? "heart.fill" : "heart.fill" " 会出现在哪里?如果状态变量是字符串呢?
When the typeClicked = "success" the image should change, if it is other than "success" the image should retain its previous condition.
当 typeClicked = "success" 时,图片应该更改,如果不是 "success",则图片应该保持其先前的状态。
What I have tried so far:
我迄今为止尝试过的内容:
State variables:
状态变量:
@State private var type: String = "success"
@State private var typeClicked: Bool = false
@StateObject var viewModel = addWishlist()
MyView :
我的视图:
VStack{
HStack {
Image("resort1")
Spacer()
Button {
if viewModel.responses?.type == "success" {
typeClicked.toggle()
} else {
typeClicked = false
}
} label: {
Image(systemName: self.typeClicked ? "heart.fill" : "heart.fill")
.font(.system(size: 25))
.foregroundColor(self.typeClicked ? .red : Color.init(uiColor: .systemGray3))
}
}
.padding()
}
Network class:
网络类:
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
                    print(decodedData.record)
                    print(decodedData.type)
                }
            } else {
                print("No data")
            }
        } catch {
            print(error)
        }
    }
    task.resume()
}
}
structs:
结构体:
struct add: Codable {
var type: String
let record: addRecord
}
我希望我的视图仅根据 "type" 更改。在我的 API 响应中,"type" 是 "success"。
英文:
We can change the image with the help of a button using state variable as Boolean. But how do we achieve that using a string variable?
For Example:
If State variable is a bool:-
Image(systemName: self.typeClicked ? "heart.fill" : "heart.fill")
what will come in the place of " self.typeClicked ? "heart.fill" : "heart.fill" " if the state variable is String?
When the typeClicked = "success" the image should change, if it is other than "success" the image should retain its previous condition.
What I have tried so far:
State variables:
    @State private var type: String = "success"
    
    @State private var typeClicked: Bool =  false
    
    @StateObject var viewModel = addWishlist()
MyView :
  VStack{
            HStack {
                Image("resort1")
                Spacer()
                Button {
                    if viewModel.responses?.type == "success" {
                        typeClicked.toggle()
                    } else {
                        typeClicked = false
                    }
                } label: {
                    Image(systemName: self.typeClicked ? "heart.fill" : "heart.fill")
                        .font(.system(size: 25))
                        .foregroundColor(self.typeClicked ? .red : Color.init(uiColor: .systemGray3))
                }
            }
            .padding()
        }
Network class:
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
                    print(decodedData.record)
                    print(decodedData.type)
                }
            } else {
                print("No data")
            }
        } catch {
            print(error)
        }
    }
    task.resume()
}
}
structs:
struct add: Codable {
var type: String
let record: addRecord
}
I want my view to be changed only with "type". which is "type": "success" in my api response.
答案1
得分: 0
以下是您要翻译的代码部分:
try this approach, when you want to have `typeClicked` a String:
     @State private var type: String = "success"
     @State private var typeClicked = "fail"  // <-- here
     @StateObject var viewModel = addWishlist()
     
      //.....
     
         VStack{
             HStack {
                 Image("resort1")
                 Spacer()
                 Button {
                     if viewModel.responses?.type == "success" {
                         // toggle equivalent
                         typeClicked = typeClicked == "success" ? "fail" : "success"  // <-- here
                     } else {
                         typeClicked = "fail"   // <-- here
                     }
                 } label: {
                     Image(systemName: typeClicked == "success" ? "heart.fill" : "heart")  // <-- here
                         .font(.system(size: 25))
                         .foregroundColor(typeClicked == "success" ? .red : Color.init(uiColor: .systemGray3))  // <-- here
                 }
             }
             .padding()
         }
 Note, you could also just use `Image(systemName: "heart.fill")` and just play with the filling color,
 `.foregroundColor(typeClicked == "success" ? .red : Color.init(uiColor: .systemGray3))`
 EDIT-1:
 
 Here is my fully working code I used to test my answer. When you tap/click on
 the `heart` button, it changes color depending on the `typeClicked` String value.
    struct ContentView: View {
        @State private var type: String = "success"
        @State private var typeClicked = "fail"  // <-- here
        
        var body: some View {
            VStack{
                HStack {
                    Image("resort1")
                    Spacer()
                    Button {
                        // simulated toggle, like you had it with the Bool
                        typeClicked = typeClicked == "success" ? "fail" : "success";
                    } label: {
                        Image(systemName: "heart.fill")
                            .font(.system(size: 25))
                            .foregroundColor(typeClicked == "success" ? .red : Color.init(uiColor: .systemGray3))
                    }
                }
                .padding()
            }
        }
    }
希望这有助于您的代码工作。如果您需要进一步的帮助,请随时提出。
英文:
try this approach, when you want to have typeClicked a String:
 @State private var type: String = "success"
 @State private var typeClicked = "fail"  // <-- here
 @StateObject var viewModel = addWishlist()
 
  //.....
 
     VStack{
         HStack {
             Image("resort1")
             Spacer()
             Button {
                 if viewModel.responses?.type == "success" {
                     // toggle equivalent
                     typeClicked = typeClicked == "success" ? "fail" : "success"  // <-- here
                 } else {
                     typeClicked = "fail"   // <-- here
                 }
             } label: {
                 Image(systemName: typeClicked == "success" ? "heart.fill" : "heart")  // <-- here
                     .font(.system(size: 25))
                     .foregroundColor(typeClicked == "success" ? .red : Color.init(uiColor: .systemGray3))  // <-- here
             }
         }
         .padding()
     }
Note, you could also just use Image(systemName: "heart.fill") and just play with the filling color,
.foregroundColor(typeClicked == "success" ? .red : Color.init(uiColor: .systemGray3))
EDIT-1:
Here is my fully working code I used to test my answer. When you tap/click on
the heart button, it changes color depending on the typeClicked String value.
struct ContentView: View {
    @State private var type: String = "success"
    @State private var typeClicked = "fail"  // <-- here
  // @StateObject var viewModel = addWishlist()  // commented for testing
    
    var body: some View {
        VStack{
            HStack {
                Image("resort1")
                Spacer()
                Button {
                    // simulated toggle, like you had it with the Bool
                    typeClicked = typeClicked == "success" ? "fail" : "success"
                    // commented for testing
//                    if viewModel.responses?.type == "success" {
                          // typeClicked = "success"   // <-- alternative to toggle
//                        typeClicked = typeClicked == "success" ? "fail" : "success"
//                    } else {
//                        typeClicked = "fail"
//                    }
                } label: {
                    Image(systemName: "heart.fill")
                        .font(.system(size: 25))
                        .foregroundColor(typeClicked == "success" ? .red : Color.init(uiColor: .systemGray3))
                }
            }
            .padding()
        }
    }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论