是否可以使 SwiftUI ListMenu 具有不同的行为? [英] Is it possible to make SwiftUI ListMenu with different behaviors?
问题描述
是否可以使用 swiftUI 制作一个列表菜单,其中列表项具有不同的行为(并使用 foreach 添加到视图中)?
列表项将是模型.
EG.第一个将打开个人资料视图,第二个将打开另一个不同的视图,第三个只是简单地注销.
并用 ForEach 模型填充列表.
我正在使用 SwiftUI 列表制作更多菜单.
代码:
<预><代码>var主体:一些视图{导航视图{列表(viewModel.menuItems){ item in//这里应该显示另一个视图或根据项目类型调用一个函数//例如.如果是个人资料菜单项,则显示个人资料//如果是注销菜单项,则注销}}}继承可以很容易地与相似项共享属性,然后根据类型路由视图
导入 SwiftUI类 MenuOption: ObservableObject, Identifiable{var id: UUID = UUID()@Published var 标题:字符串初始化(标题:字符串){self.title = 标题}}MOToggle 类:MenuOption{@Published var 值:布尔值init(title: String, value: Bool = false){self.value = 价值super.init(标题:标题)}}MOOptions 类:MenuOption{@Published var 选择:选项枚举选项:字符串,CaseIterable{案例优先案例二案例三案件不明}init(title: String, selection: Options = .unknown){self.selection = 选择super.init(标题:标题)}}//您可以拥有使用每种类型的视图struct MenuOptionToggleView:查看{@ObservedObject var 选项:MOTogglevar主体:一些视图{切换(isOn:$option.value,标签:{文本(选项.标题)})}}struct MenuOptionOptionsView:查看{@ObservedObject var 选项:MOOptionsvar主体:一些视图{选择器(选择:$option.selection,标签:文本(选项.标题), 内容: {ForEach(MOOptions.Options.allCases, id:\.rawValue, content: { item in文本(item.rawValue).tag(item)})}).pickerStyle(MenuPickerStyle())}}//并在一个视图中显示它们struct MenuListView:查看{//当他们共享一个类型时,他们可以一起放在一个数组中@State var options: [MenuOption] = [MenuOption(title: "say hello"),MOToggle(title: "toggle the option"), MOOptions(title: "show the menu")]var主体:一些视图{List(options, id: \.id){option in//然后当你有项目时确定它是什么类型如果选项是 MOToggle{//当你把它传递给它指定的View时//您将其转换为其特定类型MenuOptionToggleView(选项:选项为!MOToggle)} else if option 是 MOOptions{//当你把它传递给它指定的View时//您将其转换为其特定类型MenuOptionOptionsView(option: option as! MOOptions)} 别的{//并且由于它们是相同的类型,因此您可以一网打尽按钮(动作:{打印(选项.标题)}, 标签: {文本(选项.标题)})}}}}struct MenuListView_Previews: PreviewProvider {静态 var 预览:一些视图 {菜单列表视图()}}
Is it possible to make a list menu with swiftUI where the List items have different behaviors(and added to the view with foreach)?
The list items would be models.
EG. the first would open a Profile view, the second would open another different view, the third would just simply log out.
And fill the List with a ForEach of the models.
I'm making a MoreMenu with SwiftUI list.
Code:
var body: some View {
NavigationView {
List(viewModel.menuItems) { item in
//Here should show another view or call a function depending on the item type
//EG. if its a profile Menu item, show profile
// if its a logout Menu item, logout
}
}
}
Inheritance makes it easy to share properties with similar items and then routing Views depending on the type
import SwiftUI
class MenuOption: ObservableObject, Identifiable{
var id: UUID = UUID()
@Published var title: String
init(title: String){
self.title = title
}
}
class MOToggle: MenuOption{
@Published var value: Bool
init(title: String, value: Bool = false){
self.value = value
super.init(title: title)
}
}
class MOOptions: MenuOption{
@Published var selection: Options
enum Options: String, CaseIterable{
case first
case second
case third
case unknown
}
init(title: String, selection: Options = .unknown){
self.selection = selection
super.init(title: title)
}
}
//You can have Views that use each type
struct MenuOptionToggleView: View {
@ObservedObject var option: MOToggle
var body: some View {
Toggle(isOn: $option.value, label: {
Text(option.title)
})
}
}
struct MenuOptionOptionsView: View {
@ObservedObject var option: MOOptions
var body: some View {
Picker(selection: $option.selection, label:
Text(option.title)
, content: {
ForEach(MOOptions.Options.allCases, id:\.rawValue, content: { item in
Text(item.rawValue).tag(item)
})
}).pickerStyle(MenuPickerStyle())
}
}
//And show them all in one View
struct MenuListView: View {
//When they share a type they can be put in an array together
@State var options: [MenuOption] = [MenuOption(title: "say hello"),MOToggle(title: "toggle the option"), MOOptions(title: "show the menu")]
var body: some View {
List(options, id: \.id){option in
//Then when you have the item determine what type it is
if option is MOToggle{
//When you pass it to its designated View
//You convert it to its specifc type
MenuOptionToggleView(option: option as! MOToggle)
} else if option is MOOptions{
//When you pass it to its designated View
//You convert it to its specifc type
MenuOptionOptionsView(option: option as! MOOptions)
} else{
//And since they are if the same type you can have a catch all
Button(action: {
print(option.title)
}, label: {
Text(option.title)
})
}
}
}
}
struct MenuListView_Previews: PreviewProvider {
static var previews: some View {
MenuListView()
}
}
这篇关于是否可以使 SwiftUI ListMenu 具有不同的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!