【问题标题】:How to implement a custom view modifier如何实现自定义视图修饰符
【发布时间】:2020-08-12 15:32:18
【问题描述】:

明确地说,我不是询问如何使用 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")}

但是,我没有出现任何文本,并且我连接的用于打印项目属性中的内容的调试按钮打印出 nil,因此由于某种原因,该函数没有设置项目属性作为文本(“测试测试”)。

我是不是完全走错了路?有人可以说明我如何才能实现所需的行为吗?

【问题讨论】:

    标签: ios swiftui


    【解决方案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 测试

    【讨论】:

    • 感谢您的回答!这确实有效。我想知道这是否真的是实现这类事情的正确方法?我想知道 .navigationBarItems(trailing: ) 修饰符是这样实现的吗?
    • @テッド,标准组件的具体实现方式只有 Apple 知道,但考虑的变体当然不是其中之一,可能的替代方案是视图首选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 2021-11-21
    • 1970-01-01
    相关资源
    最近更新 更多