【问题标题】:How to return a Button from a function in SwiftUI?如何从 SwiftUI 中的函数返回按钮?
【发布时间】:2019-08-02 08:29:27
【问题描述】:

我需要根据一些参数动态创建一个Button

func buildButton(parameter : Parameter) -> Button {
        switch (parameter){
            case Parameter.Value1:
                return Button(
                    action: {
                        ...
                },
                    label: {
                        ...
                }
            )
            case Parameter.Value2:
                return Button(
                    action: {...},
                    label: {
                        ...
                }
            )
        }
    }

但是编译器给了我这个错误:

对泛型“按钮”的引用需要在 <...> 中使用参数。插入'>'

所以如果我点击Fix,函数声明就变成了

func buildButton(parameter : Parameter) -> Button<Label:View>

编译器给出

使用未声明的类型''

我需要在此处插入什么才能返回Button

【问题讨论】:

标签: swift button swiftui


【解决方案1】:

我不确定获得 Button 有多重要,但如果您只需要在另一个 SwiftUI 视图中显示而无需进一步改进,则可以返回 some View。您只需将所有按钮嵌入到 AnyView 中。

func buildButton(parameter : Parameter) -> some View {
        switch (parameter){
            case Parameter.Value1:
                return AnyView(Button(
                    action: {
                        ...
                },
                    label: {
                        ...
                })
            )
            case Parameter.Value2:
                return AnyView(Button(
                    action: {...},
                    label: {
                        ...
                })
            )
        }
    }

【讨论】:

  • 这正是我想要的。来自 Flutter/React Native 背景,如果我只需要返回一个小部件/组件,我可以在函数声明中声明一个返回类型为 some View,组件包装在 AnyView
  • 至少从 Xcode 12 开始,我发现我不需要在 AnyView 中嵌入 Button。没有它也能正常工作,所以代码更简洁。
【解决方案2】:

如果你看Button的声明,你可以看到它是一个泛型struct,所以你需要提供它的泛型类型参数。

struct Button<Label> where Label : View

确保将 YourView 替换为您要返回的实现 View 的实际类型。

class YourView: View { ... }

func buildButton(parameter : Parameter) -> Button<YourView> {
    switch (parameter){
        case Parameter.Value1:
            return Button(
                action: {
                    ...
            },
                label: {
                    ...
            }
        )
        case Parameter.Value2:
            return Button(
                action: {...},
                label: {
                    ...
            }
        )
    }
}

【讨论】:

  • 谢谢,我明白了。我已将 重命名为 Button 所在的结构名称。现在我有一个不同的问题:如果我尝试插入图像作为标签,label: { Image(systemName: "magnifyingglass").foregroundColor(App.Colors.NavBar.Foreground) } 编译器会给出错误Cannot convert value of type 'some View' to closure result type 'YourView'
猜你喜欢
  • 2021-06-30
  • 2016-04-01
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多