gpt4 book ai didi

swift - 如何使用 SwiftUI 制作单选列表

转载 作者:行者123 更新时间:2023-12-03 15:52:37 25 4
gpt4 key购买 nike

我正在创建单个选择列表以在我的应用程序的不同位置使用。

问题:

有没有我不知道的简单解决方案?

如果没有,我该如何完成当前的解决方案?

我的目标:

  • 始终只选择一项或一项或一项未选择的列表(取决于配置)
  • 透明背景
  • 在项目选择上 - 执行通过 init() 方法设置为参数的操作。 (该操作需要选定的项目信息。)
  • 以编程方式更改列表数据并将选择重置为第一项

  • 我目前的解决方案如下:
    List view with second item selected

    我不能使用 Picker,因为外部操作(目标编号 3)非常耗时。所以我认为它不会顺利进行。
    很可能在 SwiftUI 中有解决我的问题的方法,但是我错过了它,因为我是 swift 新手,或者据我所知,SwiftUI 中的所有内容都不能完美运行,例如:List 的透明背景(这就是为什么我需要清除init()) 中的背景。

    所以我开始自己实现选择,并停在这里:
    单击项目(按钮)时,我当前的解决方案不会更新 View 。 (仅外出并返回页面更新 View )。并且仍然可以选择多个项目。
    import SwiftUI

    struct ModuleList: View {
    var modules: [Module] = []
    @Binding var selectionKeeper: Int
    var Action: () -> Void


    init(list: [Module], selection: Binding<Int>, action: @escaping () -> Void) {
    UITableView.appearance().backgroundColor = .clear
    self.modules = list
    self._selectionKeeper = selection
    self.Action = action
    }

    var body: some View {
    List(){
    ForEach(0..<modules.count) { i in
    ModuleCell(module: self.modules[i], action: { self.changeSelection(index: i) })
    }
    }.background(Constants.colorTransparent)
    }

    func changeSelection(index: Int){
    modules[selectionKeeper].isSelected = false
    modules[index].isSelected = true
    selectionKeeper = index
    self.Action()
    }
    }

    struct ModuleCell: View {
    var module: Module
    var Action: () -> Void

    init(module: Module, action: @escaping () -> Void) {
    UITableViewCell.appearance().backgroundColor = .clear
    self.module = module
    self.Action = action
    }

    var body: some View {
    Button(module.name, action: {
    self.Action()
    })
    .frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
    .modifier(Constants.CellSelection(isSelected: module.isSelected))
    }
    }

    class Module: Identifiable {
    var id = UUID()
    var name: String = ""
    var isSelected: Bool = false
    var address: Int

    init(name: String, address: Int){
    self.name = name
    self.address = address
    }
    }

    let testLines = [
    Module(name: "Line1", address: 1),
    Module(name: "Line2", address: 3),
    Module(name: "Line3", address: 5),
    Module(name: "Line4", address: 6),
    Module(name: "Line5", address: 7),
    Module(name: "Line6", address: 8),
    Module(name: "Line7", address: 12),
    Module(name: "Line8", address: 14),
    Module(name: "Line9", address: 11),
    Module(name: "Line10", address: 9),
    Module(name: "Line11", address: 22)
    ]

    测试一些想法:

    尝试在 ModuleList 中添加 (isSelected: Bool) 的 @State 数组并将其绑定(bind)到可能更新 View 的 Module isSelected 参数...但失败然后在 init() 中填充此数组,因为 @State 数组参数在 .append( )... 也许添加函数 setList 可以解决这个问题,而我的目标是 Nr。 4. 但我不确定这是否会真正更新我的观点。
    struct ModuleList: View {
    var modules: [Module] = []
    @State var selections: [Bool] = []


    init(list: [String]) {
    UITableView.appearance().backgroundColor = .clear
    selections = [Bool] (repeating: false, count: list.count) // stays empty
    let test = [Bool] (repeating: false, count: list.count) // testing: works as it should
    selections = test
    for i in 0..<test.count { // for i in 0..<selections.count {
    selections.append(false)
    modules.append(Module(name: list[i], isSelected: $selections[i])) // Error selections is empty
    }
    }

    var body: some View {
    List{
    ForEach(0..<modules.count) { i in
    ModuleCell(module: self.modules[i], action: { self.changeSelection(index: i) })
    }
    }.background(Constants.colorTransparent)
    }
    func changeSelection(index: Int){
    modules[index].isSelected = true
    }
    }

    struct ModuleCell: View {
    var module: Module
    var Method: () -> Void

    init(module: Module, action: @escaping () -> Void) {
    UITableViewCell.appearance().backgroundColor = .clear
    self.module = module
    self.Method = action
    }

    var body: some View {
    Button(module.name, action: {
    self.Method()
    })
    .frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
    .modifier(Constants.CellSelection(isSelected: module.isSelected))
    }
    }

    struct Module: Identifiable {
    var id = UUID()
    var name: String = ""
    @Binding var isSelected: Bool

    init(name: String, isSelected: Binding<Bool>){
    self.name = name
    self._isSelected = isSelected
    }
    }

    let testLines = ["Line1","Line2","Line3","Line4"
    ]

    最佳答案

    实现这一点的最简单方法是在包含带有选择的列表的 View 中使用@State,并将其作为@Binding 传递给单元格:

    struct SelectionView: View {

    let fruit = ["apples", "pears", "bananas", "pineapples"]
    @State var selectedFruit: String? = nil

    var body: some View {
    List {
    ForEach(fruit, id: \.self) { item in
    SelectionCell(fruit: item, selectedFruit: self.$selectedFruit)
    }
    }
    }
    }

    struct SelectionCell: View {

    let fruit: String
    @Binding var selectedFruit: String?

    var body: some View {
    HStack {
    Text(fruit)
    Spacer()
    if fruit == selectedFruit {
    Image(systemName: "checkmark")
    .foregroundColor(.accentColor)
    }
    } .onTapGesture {
    self.selectedFruit = self.fruit
    }
    }
    }

    关于swift - 如何使用 SwiftUI 制作单选列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58613503/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com