实战问题
我正在尝试使用 SwiftUI 轮选择器让用户进行语言选择,但选择器坚持列表中的第一项,并且在尝试滚动时没有滚动到新选择。这发生在模拟器和物理设备上。
我认为的轮子选择器:
Picker("", selection: $model.selectedLanguageIndex, content: {
ForEach(0..<model.languages.count, id: \.self) { index in
Text(model.languages[index].name).tag(index)
}
}).pickerStyle(.wheel)
该视图具有声明的视图模型:
@StateObject private var model = MyView.viewModel()
并且视图onAppear在父元素外标签处也有一个函数:
.onAppear(perform: model.load)
视图模型如下所示:
extension MyView {
class viewModel: ObservableObject {
@Published var languages = [language]()
@Published var selectedLanguageIndex = 0
func load() {
MyService.getLanguages { (success, error, languages) in
guard success, error == nil, let languages = languages, !languages.isEmpty else { return }
DispatchQueue.main.async { self.languages = languages }
}
}
}
}
与集合一起language使用的模型languages:
struct language: Hashable, Identifiable {
let id: String
let code: String
let name: String
}
环境:
Xcode 13.2
Mac Mini M1 2020 macOS Monterey (Dev machine)
iPhone 11 Pro Max iOS 15.1 (Physical device used for testing)
解决方案
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@StateObject private var model = ContentView.viewModel()
var body: some View {
Picker("", selection: $model.selectedLanguageIndex, content: {
ForEach(0..<model.languages.count, id: \.self) { index in
Text(model.languages[index].name).tag(index)
}
}).pickerStyle(.wheel)
.onAppear {
model.load()
}
}
}
extension ContentView {
class viewModel: ObservableObject {
@Published var languages = [Language]()
@Published var selectedLanguageIndex = 0
func load() {
// MyService.getLanguages { (success, error, languages) in
// guard success, error == nil, let languages = languages, !languages.isEmpty else { return }
// DispatchQueue.main.async { self.languages = languages }
// }
// for testing
languages = [Language(id: "1", code: "1", name: "name 1"),
Language(id: "2", code: "2", name: "name 2"),
Language(id: "3", code: "3", name: "name 3"),
Language(id: "4", code: "4", name: "name 4")]
}
}
}
struct Language: Hashable, Identifiable {
let id: String
let code: String
let name: String
}
注意:就我个人而言,我会将我的viewModel外部extension设置为视图。
精品教程推荐
加入我们一起学习SwiftUI
QQ:3365059189
SwiftUI技术交流QQ群:518696470
教程网站:www.openswiftui.com