首页 > 解决方案 > 如何使快捷方式/绑定到类内的结构?(斯威夫特用户界面)

问题描述

在我的课堂上,我有一个数组Item和一个可选的 var selection,它应该将一个 SHORTCUT 存储到所选项目。我需要能够通过引用来访问选定的项目selection

为了使选择作为快捷方式起作用,选择必须是Binding? 如果是的话,它是@Binding在结构中,还是可能Binding<T>?它必须是@Published吗?

我的代码:

import SwiftUI

struct Item: Identifiable, Equatable {
    var id = UUID().uuidString
    var color: Color
}

class Model: ObservableObject {
    @Published var items: [Item] = [Item(color: .blue), Item(color: .blue), Item(color: .blue)]
    @Published var selection: Item? //this supposed to be not a value, but a SHORTCUT to a selected item inside array
    
    func setSelection (item: Item) {
        selection = item
    }
    
    func changeColor (color: Color) {
        if selection != nil {
            selection?.color = color// << PROBLEM is that it only copies object and modifies the copy instead of original
        }
    }
}

struct ContentView: View {
    @StateObject var model = Model()
    var body: some View {
        //list
        VStack {
            ForEach(model.items.indices, id:\.hashValue) { i in
                SubView(item: $model.items[i], model: model)
            }
            // change color button
            Button {
                model.changeColor(color: .red)
            } label: {Text("Make Selection Red")}
            
        }.padding()
    }
}

struct SubView: View {
    @Binding var item: Item
    var model: Model
    
    var body: some View {
        VStack {
            // button which sets selection to an items inside this subview
            Button {
                model.setSelection(item: item)
            } label: {
                Text("Select").background(item.color)}.buttonStyle(PlainButtonStyle())
        }
    }
}

所需功能:单击一个如果项目,然后充电它的颜色。

标签: classstructswiftuibindingshortcut

解决方案


因为您希望选择是“....数组内的选定项目”,所以您可以只使用项目数组中的索引。像这样:(虽然你的代码逻辑对我来说有点奇怪,但我认为这只是一个测试示例)

struct Item: Identifiable, Equatable {
    var id = UUID().uuidString
    var color: Color
}

class Model: ObservableObject {
    @Published var items: [Item] = [Item(color: .blue), Item(color: .blue), Item(color: .blue)]
    @Published var selection: Int?   // <-- here

    func changeColor(color: Color) {
        if let ndx = selection {     // <-- here
            items[ndx].color = color
        }
    }
}

struct ContentView: View {
    @StateObject var model = Model()
    var body: some View {
        //list
        VStack {
            ForEach(model.items.indices, id:\.self) { i in
                SubView(index: i, model: model)  // <-- here
            }
            // change color button
            Button {
                model.changeColor(color: .red)
            } label: {Text("Make Selection Red")}

        }.padding()
    }
}

struct SubView: View {
    var index: Int   // <-- here
    @ObservedObject var model: Model  // <-- here

    var body: some View {
        VStack {
            // button which sets selection to an items inside this subview
            Button {
                model.selection = index
            } label: {
                Text("Select").background(model.items[index].color)  // <-- here
            }
            .buttonStyle(PlainButtonStyle())
        }
    }
}

推荐阅读