这个例子是有效的,但是如果我需要添加一个 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()
}
}
如何将回调作为参数传递?
它可以像
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
}
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)
}
}