如何实现自定义视图修饰符

时间:2020-04-28 17:47:15

标签: ios swiftui

为了清楚起见,我询问如何使用ViewModifier协议创建带有body函数的结构,然后可以将其用于修改视图。这个问题有点不同。

我正在尝试创建一个可重用的NavigationView结构的替代方法,该结构在使用@Viewbuilder启用尾随闭包语法方面非常成功,这使我能够使用这样命名为“ NavBarView”的视图:

NavBarView(foregroundColor: .gray) {
        Text("Child view")
    }

使用以下初始化程序:

init(foregroundColor: Color, @ViewBuilder content: () -> Content) {
    self.foregroundColor = foregroundColor
    self.content = content()
}

如果您愿意,我可以在此处发布NavBarView结构的所有代码,但是为了简洁起见。

这段代码可以很好地编译并产生所需的效果,如下所示:

enter image description here

但是,我希望能够实现将项添加到“导航栏”的可选功能,类似于您可以在导航视图内的视图上调用.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(“测试”)。

我会完全以错误的方式进行操作吗?有人可以阐明我如何实现期望的行为吗?

1 个答案:

答案 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测试