【问题标题】:How come this SwiftUI Button extension initializer doesn't work?为什么这个 SwiftUI 按钮扩展初始化程序不起作用?
【发布时间】:2021-09-26 13:15:15
【问题描述】:

我正在尝试在 Button 上创建一个扩展,以在使用系统映像创建它们时减少样板。

extension Button {
  init(_ systemName: String, action: @escaping () -> Void) {
    self.init {
      action()
    } label: {
      Image(systemName: systemName) // <-- Error
    }
  }
}

这会导致以下编译器错误:

无法将“图像”类型的值转换为闭包结果类型“标签”

查看Button 的初始化程序,我看到它是这样声明的:

struct Button<Label> : View where Label : View {
  init(action: @escaping () -> Void, @ViewBuilder label: () -> Label) { ... }
}

但同样指定我的扩展名也不起作用。我哪里错了?

extension Button where Label : View {

【问题讨论】:

  • 也许只是创建一个自定义视图类

标签: button swiftui


【解决方案1】:

你的方法有两个直接的问题:

  1. 您需要指定Label 的类型为Image
  2. 您使用的签名将与Button (Button(_ title: StringProtocol, action: () -&gt; Void)) 的现有构造函数发生冲突

你可以用你的扩展来解决这两个问题:

extension Button where Label == Image {
  init(systemName: String, action: @escaping () -> Void) { 
    self.init(action: action, label: { Image(systemName: systemName) })
  }
}

但感觉更符合 SwiftUI 的 API 来制作自己的 Button 包装器:

struct SystemImageButton: View {
  let action: () -> Void
  let systemName: String

  init(systemName: String,
       action: @escaping () -> Void) {
    self.action = action
    self.systemName = systemName
  }

  var body: some View {
    Button(action: action,
           label: { Image(systemName: systemName) })
  }
}

【讨论】:

    【解决方案2】:

    你需要指定泛型类型,比如

    extension Button where Label == Image {   // << here !!
      init(_ systemName: String, action: @escaping () -> Void) {
        self.init {
          action()
        } label: {
          Image(systemName: systemName) // << No Error !!
        }
      }
    }
    

    使用 Xcode 12.5 / iOS 14.5 测试

    注意:详见Text标签的系统扩展如何声明

    extension Button where Label == Text {
    @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
    extension Button where Label == Text {
        public init(_ titleKey: LocalizedStringKey, action: @escaping () -> Void)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-13
      • 2012-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多