Тип выражения неоднозначен без дополнительной контекстной ошибки SwiftUI - PullRequest
0 голосов
/ 19 февраля 2020

Я сделал вид в стиле Neumorphi c с заголовком и кнопкой c neumorphi. Вид меняется, когда я включаю темный режим в коде предварительного просмотра. Затем я решил сделать переключатель, который будет включать или выключать темный режим. К сожалению, я не нашел способ дать переключателю его функциональность (но он не должен создавать никаких ошибок), и я получаю эту ошибку. У меня есть целая структура для стиля Neumorphi c, поэтому вы можете видеть термины, которые вы не знаете. Когда я убираю переключатель, ошибка исчезает.

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)
    }
}

1 Ответ

0 голосов
/ 21 февраля 2020

Я настоятельно рекомендую разделить вид и логику c вида. Общим подходом является концепция 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)
    }
}

В этом примере View напрямую связывается с переменными darkModeActivated, чтобы установить состояние кнопки переключения и backgroundColor для хранения цвета фона. Проще говоря, вы используете префикс $ в self.$viewModel.darkModeActivated, если вы изменяете значение переменной из представления. Подробное объяснение можно найти здесь . Логика c, что происходит, если изменения состояния полностью обрабатываются ViewModel.

Самой сложной частью в приведенном выше примере было получение уведомлений при изменении значения darkModeActivated. Поэтому я использовал платформу Combine для подключения подписчика, как предложено здесь .

Использование обычной кнопки для активации темного режима также довольно просто. Просто вызовите функцию ViewModel из закрытия действия кнопки. Или непосредственно переключите значение, как в примере выше.

...