表达式类型不明确,没有更多上下文错误 SwiftUI

Posted

技术标签:

【中文标题】表达式类型不明确,没有更多上下文错误 SwiftUI【英文标题】:Type of expression is ambiguous without more context error SwiftUI 【发布时间】:2020-02-19 11:44:14 【问题描述】:

我制作了一个带有标题和 neumorphic 按钮的 Neumorphic 样式视图。当我在预览代码中打开暗模式时,视图会发生变化。 然后我决定做一个开关来打开或关闭暗模式。不幸的是,我还没有找到一种方法来赋予切换功能(但它不应该产生任何错误),我得到了这个错误。我之前有一个完整的 Neumorphic 风格结构,这就是为什么你可能会看到你不知道的术语。当我移除切换开关时,错误消失了。

struct ContentView: View 

    @Environment(\.colorScheme) private var colorScheme
    @State private var isToggle : Bool = false

    var body: some View 

        ZStack 
            VStack 

                Text("Neumorphism") <- Type of expression is ambiguous without more context
                    .font(.system(size: 32,
                                  weight: .bold,
                                  design: .rounded))
                    .padding(20)

                Button("Hello world", action:  )
                    .padding(20)

            
            .frame(minWidth: 0, maxWidth: .infinity,
                   minHeight: 0, maxHeight: .infinity,
                   alignment: .center)
                .background(backgroundColor)
                .buttonStyle(NeumorphicButtonStyle(colorScheme: colorScheme))
                .edgesIgnoringSafeArea(.all)

            Toggle(isOn: $isToggle) 
                 Text("Dark Mode") <- How could I make this turn on and off dark mode?

            
        

    
    var backgroundColor: Color 
        switch colorScheme 
        case .light: return NeumorphicButtonStyle.Appearance().lightColor
        case .dark: return NeumorphicButtonStyle.Appearance().darkColor
        @unknown default: return NeumorphicButtonStyle.Appearance().lightColor
        
    

struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
            .environment(\.colorScheme, .light)
    

【问题讨论】:

没有观察到错误(当移除不可用的 NeumorphicButtonStyle 相关部分时)。使用 Xcode 11.2 / ios 13.2 测试。 【参考方案1】:

我强烈建议将视图和视图的逻辑分开。一种常见的方法是MVVM 概念。我在下面的例子中加入了这个概念(用 Xcode 11.3.1 测试):

import SwiftUI
import Combine

final class ContentViewModel: ObservableObject 
    @Published var darkModeActivated: Bool
    @Published var backgroundColor: Color

    private var sink: AnyCancellable?

    init() 
        self.darkModeActivated = false
        self.backgroundColor = Color.white

        self.sink = self.$darkModeActivated.sink()  value in
            if value 
                self.backgroundColor = Color.black
             else 
                self.backgroundColor = Color.white
            
        
    

    public func toggleDarkmode() 
        self.darkModeActivated.toggle()
    


struct ContentView: View 
    @ObservedObject var viewModel: ContentViewModel

    var body: some View 
        ZStack 
            VStack 
                Text("Neumorphism")
                    .font(.system(size: 32,
                                  weight: .bold,
                                  design: .rounded))
                    .padding(20)

                Button("Hello world", action:  self.viewModel.toggleDarkmode() )
                    .padding(20)
                Button("Hello world2", action:  self.viewModel.darkModeActivated.toggle() )
                    .padding(20)

            
            .frame(minWidth: 0, maxWidth: .infinity,
                   minHeight: 0, maxHeight: .infinity,
                   alignment: .center)
                .background(self.viewModel.backgroundColor)
                .edgesIgnoringSafeArea(.all)

            Toggle(isOn: self.$viewModel.darkModeActivated) 
                 Text("Dark Mode")
            
        
    

struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView(viewModel: .init())
            .environment(\.colorScheme, .light)
    

在示例中,视图直接绑定变量darkModeActivated 来设置切换按钮的状态,backgroundColor 来存储背景颜色。简单地说,如果您从视图中更改变量的值,您可以在self.$viewModel.darkModeActivated 中使用$ 前缀。可以在here找到全面的解释。如果状态更改完全由 ViewModel 处理,会发生什么逻辑。

上面示例中最困难的部分显然是在darkModeActivated 的值发生变化时得到通知。因此,我按照here 的建议使用了 Combine 框架来附加订阅者。

使用普通按钮激活暗模式也很容易。只需从按钮的操作闭包中调用 ViewModel 函数。或者像上面的例子一样直接切换值。

【讨论】:

这太完美了!效果很好。您认为我如何将其合并到按钮本身中? “进入按钮本身”是什么意思?您希望您的“Hello World”按钮具有类似的行为吗? 是的,所以每次我点击按钮时,它都会切换颜色模式,就像拨动开关一样。 这很容易。我在上面的答案中编辑了示例。

以上是关于表达式类型不明确,没有更多上下文错误 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

Swift 错误:表达式类型不明确,没有更多上下文

Swiftui 错误:表达式类型不明确,没有更多上下文

表达式类型不明确,没有更多上下文错误 SwiftUI

Xcode:在 UISlider 中没有更多上下文错误的表达式类型不明确

在准备函数中卡住“表达式类型不明确,没有更多上下文”

Xcode:表达式类型不明确,没有更多上下文