Я настоятельно рекомендую разделить вид и логику 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 из закрытия действия кнопки. Или непосредственно переключите значение, как в примере выше.