如何使用 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()
}
}
效率不是很高,但我相信您会找到更好的方法来重新加载数据。
我正在制作这个使用 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()
}
}
效率不是很高,但我相信您会找到更好的方法来重新加载数据。