SwiftUI : DarkMode 구현하기 - Environment
.DarkMode
적용 법에 대해 알아보도록 합시다.
DarkMode
SwiftUI
에서 사용자가 DarkMode
인지 LightMode
인지에 따라 앱 화면을 자동으로 설정해줄 수 있는 기능이 있습니다. 이것을 사용하기 위해서는 Environment
에 대한 기본적인 지식이 있어야 합니다.
우선 간단하게 화면에 Alert
버튼과 배경화면을 설정해주겠습니다.
배경화면 및 버튼 추가
ZStack {
//1.배경설정
Color.yellow
.edgesIgnoringSafeArea(.all)
VStack {
Spacer()
//2. 버튼생성
Button(action: {
print("버튼이 눌렸습니다.")
}, label: {
Text("서근 블로그")
.font(.system(size: 20))
.fontWeight(.bold)
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10).stroke(Color.white, lineWidth: 2))
})
}
}
Alert
Alert
를 사용하기 위해서 @State
값을 bool
타입으로 가져와주겠습니다.
struct Darkmode: View {
@State private var showingAlert = false
var body: some View {
ZStack { ... }
}
}
그리고 Button action
에 .self.showingAlert.toggle()
를 추가하고 바깥쪽에 Alert
코드를 작성합니다.
ZStack {
...
VStack {
Button(action: {
self.showingAlert.toggle()
}, label: {
Text("서근 블로그")
...
})
.alert(isPresented: $showingAlert, content: {
Alert(title: Text("열심히 코딩합시다😁"), message: Text("나태해 지지 말자🔥"),
dismissButton: .default(Text("닫기")))
})
}
}
DarkMode Struct 생성
다크 모드를 사용하기 위해서 테마를 하나 생성해줘야 합니다.
이름을 Theme
으로 설정하고 Static
에 함수를 작성해주겠습니다. 우리는 Environment
를 사용해야 하기 때문에 여기서 필요한 것이 ColorScheme
입니다.
매개변수를 scheme
으로 설정하고 Color
를 반환해주겠습니다.
light 모드일 때 컬러와 dark 모드일 때의 컬러도 가져와 줍니다.
struct Theme {
static func myBackgroundColor(forScheme scheme: ColorScheme) -> Color {
let lightColor = Color(Literal)
let darckColor = Color.black
}
이제 조건문을 넣어줘야 하는데 if
문대신 switch
문을 사용하겠습니다. ColorScheme
는 .light
와 .dark
값이 기본적으로 포함되어있습니다. 각 light와 dark값에 lightColor
/ darkColor
를 반환해줘야 됩니다.
한 가지 중요한 것이 있는데 스킨 같은 경우에는 반드시 @unknown default
를 작성해줘야 합니다. 이것은 기본값에 해당합니다.(다크 모드를 기본으로 할 것인지, 라이트 모드를 기본으로 할 것인지..)
struct Theme {
static func myBackgroundColor(forScheme scheme: ColorScheme) -> Color {
let lightColor = Color(#colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1))
let darckColor = Color.black
switch scheme {
case .light : return lightColor
case .dark : return darckColor
@unknown default: return lightColor
}
}
}
Environment
뷰의 환경 값이 바뀌게 되었을 때 그것을 감지하는 Enviornment
태그를 가져와줘야 합니다.
struct Darkmode: View {
@State private var showingAlert = false
@Environment(\.colorScheme) var scheme
var body: some View {
}
}
자, 이렇게 Environment
값을 가져왔고 이제 이것을 ZStack
Color
에 사용해주겠습니다.
배경화면에 다크 모드 적용
처음에 넣어줬던 Color.yellow
를 지우고 우리가 만들었던 Theme
의 myBackgoundColor
를 가져와줘야 합니다.
이제 Theme.myBackgroundColor(forScheme: ColorScheme)
이 코드에 ColorScheme
을 지우고 Environment
에 변수로 넣어준 scheme
을 할당해주면 됩니다.
ZStack {
Theme.myBackgroundColor(forScheme: scheme)
.edgesIgnoringSafeArea(.all)
}
실행
이제 앱을 실행해보면 정상적으로 배경이 바뀐 것을 확인 할 수 있고, 또 Alert
창도 자동으로 바뀐것을 알 수 있습니다 :)
전체 코드
<hide/>
import SwiftUI
struct ContentView: View {
//Alert
@State private var showingAlert = false
//다크모드인지 아닌지를 정해주는 환경설정
@Environment(\.colorScheme) var scheme
var body: some View {
ZStack {
// Color.yellow
Theme.myBackgroundColor(forScheme: scheme)
.edgesIgnoringSafeArea(.all)
VStack {
Spacer()
Button(action: {
print("버튼이 눌렸습니다.")
self.showingAlert.toggle()
}) {
Text("서근 블로그")
.font(.system(size: 20))
.fontWeight(.bold)
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10).stroke(Color.white, lineWidth: 2))
}
.alert(isPresented: $showingAlert, content: {
Alert(title: Text("열심히 코딩합시다😁"), message: Text("나태해 지지 말자🔥"), dismissButton: .default(Text("닫기")))
})
Spacer().frame(height:100)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
//다크모드 테마 생성
struct Theme {
static func myBackgroundColor(forScheme scheme: ColorScheme) -> Color {
let lightColor = Color.white
let darckColor = Color.black
switch scheme {
case .light : return lightColor
case .dark : return darckColor
@unknown default: return lightColor
}
}
}
Color 비교
위처럼 함수를 만들어서 Dark모드를 정의해줄 수 있지만 간단하게 표현도 가능합니다. 우선 시스템에 있는 기본코드로 비교해가면서 알아보도록 하겠습니다.
우선 colorScheme을 사용하려면 Environment를 추가해줘야겠죠?
import SwiftUI
struct DarkModeView: View {
@Environment(\.colorScheme) var colorScheme
var body: some View {
}
}
import SwiftUI
struct DarkModeView: View {
@Environment(\.colorScheme) var colorScheme
var body: some View {
VStack{
Text("Primary Color")
.foregroundColor(.primary)
Text("Secondary Color")
.foregroundColor(.secondary)
Text("Black Color")
.foregroundColor(.black)
Text("White Color")
.foregroundColor(.white)
Text("Assets에 추가한 Color")
.foregroundColor(Color("MyColor"))
Text("Environment colorScheme")
.foregroundColor(colorScheme == .light ? .orange : .yellow)
}
}
}
struct DarkModeView_Previews: PreviewProvider {
static var previews: some View {
Group {
DarkModeView()
.preferredColorScheme(.light)
DarkModeView()
.preferredColorScheme(.dark)
}
}
}
읽어주셔서 감사합니다🤟
본 게시글의 전체 코드 GitHub 👇🏻
[SwiftUI 기초/Others] - SwiftUI : EnvironmentObject '뷰간에 데이터 공유'
[SwiftUI 기초/View layout] - SwiftUI : Sheet (@Environment / presentationMode)