如何使用 SwiftUI 中用户的输入更改 url 字符串

How to change the url string with inputs from the user in SwiftUI

我正在制作这个使用 jikan API 来显示动漫列表的应用程序,因此在 url 中有一个选项可以更改类型 - 动漫、漫画等,子类型 - 即将上映、电视、电影等,API 工作正常并且正在获取详细信息,但现在我想在表单视图中显示两个选择器,最好允许用户 select 键入和子类型因此我为选择器使用了@State属性但是当我运行应用程序和select与选择器

不同的值时它没有更新列表

这是代码-

import SwiftUI


struct Response: Codable{
    var top: [Result]
    
}

struct Result: Codable {
    
    var mal_id: Int
    var rank: Int
    var title: String
    var type: String
    var start_date: String?
    var image_url: String
    
}

struct ContentView: View {
    
    @State private var str2 = ""
   @State private var str3 = ""
    
    func loadData() {

         str3 = String("/\(subtype[subTypeSelection])")
        
         str2 = String("\(type[typeSelection])/")
        
        let str1 = "https://api.jikan.moe/v3/top/"
        
        guard let url = URL(string: str1 + str2 + "\(1)" + str3) else {
            print("Invalid URL")
            return
        }
        
        
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
                    // we have good data – go back to the main thread
                    DispatchQueue.main.async {
                        // update our UI
                        self.top = decodedResponse.top
                    }
                    // everything is good, so we can exit
                    return
                }
            }
            // if we're still here it means there was a problem
            print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
        }.resume()
    }

     var type = ["anime", "manga", "people", "characters"]
     var subtype = ["airing", "upcoming", "tv", "movie", "ova", "special"]
    
    
    @State private var page = 1
    @State private var typeSelection = 0
    @State private var subTypeSelection = 2
   
    @State private var top = [Result]()
    var body: some View {
//        ScrollView {
        VStack {
       
            Picker("Your  Selection", selection: $subTypeSelection) {
                
                ForEach(0 ..< 6) {
                    somehting in
                    Text("\(subtype[somehting])")
                }
            }
                Picker("Your  Selection", selection: $typeSelection) {
                    
                    ForEach(0 ..< 4) {
                        somehting in
                        Text("\(type[somehting])")
                    }
                }
        }
        
//        .onAppear(perform: {
//            loadData()
//        })
            List(top, id: \.mal_id) { item in
                
                HStack {
                    AsyncImage(url: URL(string: item.image_url)!,
                                   placeholder: { Text("Loading ...") },
                                   image: { Image(uiImage: [=11=]).resizable() })
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 100, height: 100)
//                        .frame(idealHeight: UIScreen.main.bounds.width / 10 * 10 )
                        
                        .clipShape(Capsule())
                    VStack(alignment: .leading) {
                                Text(item.title)
                                    .font(.headline)
                                Text(String("\(item.rank)"))
                                    .font(.headline)
                                Text(item.type)
                                    .font(.headline)
                                Text(item.start_date ?? "")
                                                .font(.headline)
                                
                    }
                }
                    }
                      // }
            .onAppear(perform: loadData)
       
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

您可以尝试在每个选择器上使用“onChange”:

VStack {
    Picker("Your subtype Selection", selection: $subTypeSelection) {
        ForEach(0 ..< 6) { somehting in
            Text("\(subtype[somehting])").tag(somehting)
        }
    }.onChange(of: subTypeSelection) { value in
        loadData()
    }
    Picker("Your type Selection", selection: $typeSelection) {
        ForEach(0 ..< 4) { somehting in
            Text("\(type[somehting])").tag(somehting)
        }
    }.onChange(of: typeSelection) { value in
        loadData()
    }
}

效率不是很高,但我相信您会找到更好的方法来重新加载数据。