【问题标题】:Add view as a parameter to a custom ViewModifier将视图作为参数添加到自定义 ViewModifier
【发布时间】:2020-12-21 23:05:02
【问题描述】:

这更像是一个句法问题。我试图在不使用 AnyView 的情况下将视图传递给 ViewModifier 初始化程序。

目前我有一些使用 AnyView 运行的东西,但我想使用通用视图语法,然后将“某些视图”传递给此答案中概述的视图:

How to pass one SwiftUI View as a variable to another View struct

我似乎无法让它与 ViewModifier 一起使用。

目的(如示例中所示)是修改器将计算值传递到innerView。我也很乐意以某种方式使用 @ViewBuilder 来指定 innerView 属性,因为这可能会产生相同的效果。

这里是示例修饰符:

struct SampleModifier: ViewModifier {

    let param1: CGFloat
    let innerView:  (CGFloat, CGFloat) -> AnyView
    
    // Assume these are calculated states
    let calculatedParam1: CGFloat = 100
    let calculatedParam2: CGFloat = 100
    
    func body(content: Content) -> some View {
        ZStack {
            HStack {
                Spacer()

                innerView(self.calculatedParam1, self.calculatedParam2)
                    .padding(.leading, 10)
                    .frame(width: param1)
            }
            
            content.frame(width: 100, height: 100)
        }
        
    }
}

及其用途:

struct SampleView: View {
    var body: some View {
        Rectangle()
            .modifier(SampleModifier(param1: 150, innerView: { param1, param2 in
                return AnyView(
                    Text("Inner View: \(param1) - \(param2)")
                )
            }))
    }
}

【问题讨论】:

    标签: ios swift swiftui


    【解决方案1】:

    你可以使用泛型,即让innerView返回一些视图:

    struct SampleModifier<V>: ViewModifier where V: View {
        let param1: CGFloat
        let innerView: (CGFloat, CGFloat) -> V
    
        ...
    }
    

    那么你就不再需要AnyView了:

    struct SampleView: View {
        var body: some View {
            Rectangle()
                .modifier(SampleModifier(param1: 150, innerView: { param1, param2 in
                    Text("Inner View: \(param1) - \(param2)")
                }))
        }
    }
    

    或者,您可以创建一个View 扩展:

    extension View {
        func sampleModifier<V>(
            param1: CGFloat,
            innerView: @escaping (CGFloat, CGFloat) -> V
        ) -> some View where V: View {
            modifier(SampleModifier(param1: param1, innerView: innerView))
        }
    }
    

    并像这样使用它:

    struct SampleView: View {
        var body: some View {
            Rectangle()
                .sampleModifier(param1: 150, innerView: { param1, param2 in
                    Text("Inner View: \(param1) - \(param2)")
                })
        }
    }
    

    【讨论】:

    • 太棒了,这正是我想要的。还有一个问题,如果我要做一个视图扩展辅助函数,它会是什么样子?在结合泛型和协议时,我真的在与语法作斗争。
    • @Slappy 我用视图扩展更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多