Xcode报错:Type ‘()’ cannot conform to ‘View’
Xcode报错:Type ‘()’ cannot conform to ‘View’

Xcode报错:Type ‘()’ cannot conform to ‘View’

问题复现

在Swift UI中,想要在body中输出“print(animationAmount)”,但是会存在下面的报错:

Type '()' cannot conform to 'View'

具体的代码如下:

import SwiftUI

struct ContentView: View {
    @State private var animationAmount = 1.0

    var body: some View {
        print(animationAmount)
        
        VStack {
            Stepper("Scale amount", value: $animationAmount.animation(), in: 1...10)

            Spacer()

            Button("Tap Me") {
                withAnimation {
                    animationAmount += 1
                }
                
            }
            .padding(40)
            .background(.red)
            .foregroundStyle(.white)
            .clipShape(.circle)
//            .animation(.default, value: animationAmount)
            .scaleEffect(animationAmount)
        }
    }
}

#Preview {
    ContentView()
}

解决方案

不推荐的的解决方案为:

var body: some View {
    print(animationAmount)

    return VStack {
        // 视图内容
    }
}

推荐的解决方案:

var body: some View {
    print(animationAmount)
    VStack {
        // 视图内容
        Button("Tap Me") {
            // 视图内容
            print(animationAmount) // 在按钮的动作中打印
        }
    }
}

因此将两个解决方案拿出来,原因在于提供一个对比。print在body中输出报错的原因为,View的body部分是一个结构体属性,应该只负责描述视图的内容,而不应该提供其他的副作用。

我们的print在body中使用,会违反这一原则,也因此会产生编译器报错,提示你不应该在这里引入副作用(非视图的功能),所以,我们应该在按钮中使用print打印输出。

不推荐的解决方案中,print之所以可以工作,是因为Swift的类型推断机制,当我们在body中使用return时,Swift的类型推断机制会理解为这是一个明确的返回值,因此print才会工作,但它并不符合Swift UI声明式编程的设计理念。

还有一个不推荐的原因是,Swift UI视图的重建频率高,body会被频繁调用,当在body中放置副作用(print输出)时,会看到大量的冗余,甚至影响性能。

以上是本次的问题报错、分析和相关解决方案。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注