如何将回调传递给View init?

问题描述 投票:0回答:2

这个例子是有效的,但是如果我需要添加一个 init 来做一些准备工作,我就无法弄清楚如何传递回调。在实际代码中我需要传递几个参数并进行一些其他初始化。

import SwiftUI

struct Choices: View
{
    let choices = ["One", "Two", "Three"]
    @State var choice:String = "One"
    let callback: (String) -> ()
    
/*
init()
{
  // do stuff here
}
*/

    var body: some View
    {
        VStack(alignment: .leading)
        {
            ForEach(choices, id:\.self)
            { c in
                HStack
                {
                    Image(systemName: (choice == c) ? "checkmark.square" : "square")
                    Text(c)
                }.onTapGesture
                {
                    choice = c
                    callback(c)
                }
            }
            Divider()
        }.padding()
    }
}

struct ChoicesContentView: View
{
    @State var answers:[String] = ["","",""]
    
    var body: some View
    {
        VStack(alignment: .leading)
        {
            ForEach(0..<3)
            { i in
                Choices()
                {
                    ans in
                    print(ans)
                }
                Text("Selected: \(answers[i])")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ChoicesContentView()
    }
}

如何将回调作为参数传递?

swift swiftui callback
2个回答
2
投票

它可以像

struct Choices: View
{
    let choices = ["One", "Two", "Three"]
    @State var choice:String = "One"
    let callback: (String) -> ()
    
    init(callback: @escaping (String) -> ()) {    // << here !!
        self.callback = callback
    }
// ...
}

甚至使用默认值

init(callback: @escaping (String) -> () = { _ in }) {    // << here !!
    self.callback = callback
}

0
投票

struct ProviderScope:查看{

@EnvironmentObject public var router: Router
@Environment(\.modelContext) private var context

let content: ((Router, ModelContext?)) -> Content

init(@ViewBuilder content: @escaping ((router: Router, context: ModelContext?)) -> Content) {
    self.content = content
}

var body: some View {
    content((router, context))
}

}

在单个结构中管理公共环境变量依赖关系的方法之一。

public var body: some View {

    ProviderScope { scope in
        List {
            Section {
                ProfileHeaderView()
            }.listRowBackground(Color.clear)
                .listRowSeparator(.hidden)
            
            Section {
                HStack {
                    VStack(alignment: .leading) {
                        Text("Jack Martines")
                            .font(Font.system(size: 16))
                            .fontWeight(.medium)
                        Text("You have \(boards.count) Projects")
                            .font(Font.system(size: 14))
                            .fontWeight(.regular)
                    }
                    Spacer()
                    Button(action: {}, label: {
                        HStack(alignment: .center, spacing: 4) {
                            Image(systemName: "plus")
                                .foregroundStyle(.blue)
                            Text("Add")
                                .foregroundStyle(.blue)
                        }.padding(.all, 8)
                    })
                    .background(
                        RoundedRectangle(cornerRadius: 8)
                            .foregroundStyle(.blue.opacity(0.2))
                    )
                    .onTapGesture {
                        scope.router.push(destination: RouteConstants.BOARD_CREATE.routeIntent())
                    }
                }
            } .listRowBackground(Color.clear)
                .listRowSeparator(.hidden)
            
            Section {
                ProjectHScrollerView(router: scope.router)
            }.listRowSeparator(.hidden)
        }.listStyle(.plain)
            .listSectionSeparator(.hidden)
            .listSectionSpacing(0)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.