代码之家  ›  专栏  ›  技术社区  ›  dfd

将工具栏重构为另一个文件

  •  0
  • dfd  · 技术社区  · 6 年前

    有经验的Swift UIKit编码器,但绝对不是与SwiftUI。假设我有以下代码:

    HStack {
        Button(
            action: { self.createNode() },
            label: {
                Text("ADD").bold().font(.system(size: 40)).frame(width: 200, height: 80).background(Color.yellow).cornerRadius(5)
        })
        Spacer()
        Button(
            action: { self.deleteNode() },
            label: {
                Text("DELETE").bold().font(.system(size: 40)).frame(width: 200, height: 80).background(Color.yellow).cornerRadius(5)
        })
    }
    

    简单工具栏。但是现在,让我们再加上四个 Buttons 并将其放入“根”视图中。在UIKit中我们称之为 .

    HStack 在根视图之外,但是我对 action . 我知道我可以创造 ViewModifiers createNode() deleteNode() 其他任何地方。

    我肯定是我想装个方钉( UIKit SwiftUI ),但我找到的WWDC会话或其他资源似乎都没有为我指明正确的方向。我错过了什么?

    @State var nodes: [Node] = []
    
    func createNode() {
        let newNodeName = nodes.count + 1
        let newNode = Node(name: newNodeName)
        nodes.append(newNode)
    }
    func deleteNode() {
        if nodes.count != 0 {
            nodes.remove(at: nodes.count - 1)
        }
    }
    

    我的问题 关于Swift,或者关于维护数组。它是关于SwiftUI的,以及如何将我当前的140行文件“重构”成更小的东西——在本例中,通过在Xcode中将“顶栏”HStack删除到它自己的文件中。

    这一叠水平的按钮最终会排到第5位(这是一款仅限iPad的应用程序),我的问题是如何移动按钮“actions”,键入 () -> Void 正确地。

    HStack    
        VStack
           HStack  <-- Contains the Buttons that add/delete the nodes
           HStack
           HStack  <-- Contains the nodes themselves, will soon contain thumbnails    
        List
    

    Text 好的,很好用。但当我试图移动 Button (不管是嵌套在HStack中还是独立的)到一个单独的文件中,我会遇到构建问题。

    0 回复  |  直到 6 年前
        1
  •  1
  •   Matteo Pacini    6 年前

    @State 到视图模型中。

    final class ViewModel: BindableObject {
    
        let didChange = PassthroughSubject<Void, Never>()
    
        var nodes: [Node] = [] {
            didSet {
                didChange.send(())
            }
        }
    
        func createNode() {
            let newNodeName = nodes.count + 1
            let newNode = Node(name: newNodeName)
            nodes.append(newNode)
        }
    
        func deleteNode() {
            if nodes.count != 0 {
                nodes.remove(at: nodes.count - 1)
            }
        }
    
    }
    

    所有需要访问操作的视图都需要声明此属性:

    @EnvironmentObject var viewModel: ViewModel
    

    有关的详细信息 @EnvironmentObject here .

    您只需要在容器视图中设置环境对象,就可以将它传递给所有子视图。

    例如

    ContentView().environmentObject(ViewModel())
    

    视图层次结构

    HStack    
        VStack
           HStack  <- @EnvironmentObject (will call the actions)
           HStack
           HStack  <- @EnvironmentObject (will use viewModel.nodes to display nodes)
        List