为了清楚起见,我不询问如何使用ViewModifier协议创建带有body函数的结构,然后可以将其用于修改视图。这个问题有点不同。
我正在尝试创建一个可重用的NavigationView结构的替代方法,该结构在使用@Viewbuilder启用尾随闭包语法方面非常成功,这使我能够使用这样命名为“ NavBarView”的视图:
NavBarView(foregroundColor: .gray) {
Text("Child view")
}
使用以下初始化程序:
init(foregroundColor: Color, @ViewBuilder content: () -> Content) {
self.foregroundColor = foregroundColor
self.content = content()
}
如果您愿意,我可以在此处发布NavBarView结构的所有代码,但是为了简洁起见。
这段代码可以很好地编译并产生所需的效果,如下所示:
但是,我希望能够实现将项添加到“导航栏”的可选功能,类似于您可以在导航视图内的视图上调用.navigationBarItems(trailing:)的方式。我不确定我是否可以实现这一目标。
到目前为止,我已经尝试在NavBarView结构中创建一个名为item的可选state属性,其类型为Item符合View,如下所示:
@State var item: Item?
然后将该项目放置到HStack中,以便在非可选项目时应将其显示在“父视图”文本旁边。
然后,我在NavBarView结构中编写了以下函数:
func trailingItem(@ViewBuilder _ item: () -> Item) -> some View {
self.item = item()
return self
}
然后我试图像这样调用该函数:
NavBarView(foregroundColor: .gray) {
Text("Child view")
}.trailingItem{Text("test test")}
但是,我没有出现任何文本,我挂接用来打印出item属性中的内容的调试按钮显示为nil,因此出于某种原因该函数未设置item属性作为Text(“测试”)。
我会完全以错误的方式进行操作吗?有人可以阐明我如何实现期望的行为吗?
答案 0 :(得分:1)
这是可行的方法,对修饰符的唯一小修正
extension NavBarView {
func trailingItem(@ViewBuilder _ item: @escaping () -> Item) -> some View {
var view = self // make modifiable
view.item = item()
return view
}
}
,因此您不必将其设为@State
,只需将其声明为
fileprivate var item: Item?
通过Xcode 11.4测试