【问题标题】:Statement in SwiftUI closure body causes type errorSwiftUI 闭包体中的语句导致类型错误
【发布时间】:2020-05-17 09:52:15
【问题描述】:

SwiftUI 视图上的这个修饰符编译得很好:

.background(GeometryReader { p in
    return Rectangle().opacity(0)
})

(我知道我不需要返回,但我要添加另一行。)

当我添加 print 调用时,它不再编译。

.background(GeometryReader { p in
    print("hi")
    return Rectangle().opacity(0)
})

错误指向background并说:

表达式类型 '(_, Alignment) -> some View' 在没有更多上下文的情况下是模棱两可的

我不明白为什么它现在对传递给.background(...) 的事物类型感到困惑。它和以前一样清晰的return 表达式。如何修复代码以满足类型检查器的要求?

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    出现此错误是因为multi-statement closures don't take part in type inference。无法推断 GeometryReader 的初始化程序的 Content 泛型参数,因为您提供给它的唯一信息,闭包,不考虑类型推断!

    所以你只需要指定你要返回的类型:

    .background(GeometryReader {
        p -> Rectangle in // note here
        print("Hello")
        return Rectangle()
    })
    

    您可能不应该这样做,因为您应该只将Views 放在视图构建器闭包中。 SwiftUI 被设计成非常具有声明性,我会说几乎是它自己的 DSL。

    编辑:我找到了this answer,它添加了一个名为PrintView。我想您可以将其中一个放在您设置背景的任何视图旁边,在 Group 中。

    【讨论】:

    • 抱歉,我按照您的回答编辑了我的问题。您的回答有效,但现在我添加了 .opacity 修饰符,我不知道要使用哪种类型。写 some View 代替 Rectangle 并没有削减它。
    • @RobN 这就是为什么您不应该编写其他语句视图构建器。你应该只写Views,并且在视图构建器闭包中只写Views。您可以拥有if...else 语句,但这就是您拥有的所有控制权。正如您可能已经发现的那样,您实际上不能声明变量,或者在视图构建器中执行 for/while 循环,print 也是如此。
    • 好的,我可以根据自己的需要调整 Print 视图。从 Swift 论坛 (forums.swift.org/t/function-builders/25167) 链接到函数构建器的原始设计提案允许更多的东西,比如局部变量。所以我认为其中一些限制只是目前已经实施了一半。
    • 嗯,这并不是说你物理上不能编写变量声明。我说“实际上不能”,因为无论何时这样做,闭包都会在类型推断中被忽略。仍然可以通过其他方式推断类型,但是由于通常使用视图构建器的上下文(不透明的返回类型),类型推断几乎总是失败。
    【解决方案2】:

    编写我自己的修饰符我能够为视图创建背景。 Sweeper 我认为有正确的想法,您需要添加一个 return 语句,因为几何阅读器不再是单行隐式返回。

    extension View {
      func myBackground() -> some View {
        print("hi")
        return background(GeometryReader { geometry in
          Rectangle().path(in: geometry.frame(in: .local))
        })
      }
    }
    

    然后我在下面的上下文中测试了修饰符。

    struct ContentView: View {
    
      var body: some View {
        Text("Foreground Label").foregroundColor(.green).myBackground()
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2016-08-16
      相关资源
      最近更新 更多