如何对类内的结构进行快捷方式/绑定? (斯威夫特用户界面)

Posted

技术标签:

【中文标题】如何对类内的结构进行快捷方式/绑定? (斯威夫特用户界面)【英文标题】:How to make shortcut/binding to a struct inside class? (SwiftUI) 【发布时间】:2021-11-21 22:27:10 【问题描述】:

在我的课堂上,我有一个 Item 数组和一个可选的 var 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())
        
    

所需的功能:点击一个 if 项目,然后为它的颜色充电。

【问题讨论】:

【参考方案1】:

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

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())
        
    

【讨论】:

很高兴见到您 ;) 您的样品效果很好,谢谢!唯一的事情是我的项目项目被添加/删除了很多。所以“Int”很快就不会相关了。但是您的示例给了我一个想法:在“选择”中保留一个“UUID”,而不是尝试将其直接链接到数组中的项目。我的项目现在几乎可以工作了,除了使用 get 和 set 进行自定义绑定的问题

以上是关于如何对类内的结构进行快捷方式/绑定? (斯威夫特用户界面)的主要内容,如果未能解决你的问题,请参考以下文章

类内的结构[关闭]

类内的按钮动作选择器

如何从外部访问类内的自我对象

如何通过向它们添加组件来使滚动器内的视图自动调整大小? - 斯威夫特 3

声纳规则控制类内的最大功能数量

这种使用模板对类层次结构进行函数重载的方式安全吗?