如何使 shortcut/binding 成为 class 中的结构? (斯威夫特用户界面)
How to make shortcut/binding to a struct inside class? (SwiftUI)
在我的 class 中,我有一个 Item
数组和一个可选的变量 selection
,它应该存储所选项目的快捷方式。
我需要能够通过引用 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())
}
}
}
所需功能:点击其中一项,然后为其着色。
因为您希望选择是“....数组中的选定项目”,那么您可以
只需使用项目数组中的索引。是这样的:
(虽然你的代码逻辑对我来说有点奇怪,但我认为这只是一个测试例子)
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())
}
}
}
在我的 class 中,我有一个 Item
数组和一个可选的变量 selection
,它应该存储所选项目的快捷方式。
我需要能够通过引用 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())
}
}
}
所需功能:点击其中一项,然后为其着色。
因为您希望选择是“....数组中的选定项目”,那么您可以 只需使用项目数组中的索引。是这样的: (虽然你的代码逻辑对我来说有点奇怪,但我认为这只是一个测试例子)
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())
}
}
}