Reputation: 576
This example works, but if I need to add an init to do some prep work, I can't figure out hot to pass the callback. In the actual code I need to pass several parameters and do some other initialization.
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()
}
}
How to I pass the callback as a parameter?
Upvotes: 3
Views: 1293
Reputation: 69
struct ProviderScope<Content: View>: View {
@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))
}
}
One of the way to manage common environment variables dependency in a single struct.
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)
}
}
Upvotes: 0
Reputation: 258345
It can be like
struct Choices: View
{
let choices = ["One", "Two", "Three"]
@State var choice:String = "One"
let callback: (String) -> ()
init(callback: @escaping (String) -> ()) { // << here !!
self.callback = callback
}
// ...
}
or even with default value
init(callback: @escaping (String) -> () = { _ in }) { // << here !!
self.callback = callback
}
Upvotes: 2