SWIFTUI/Others

SwiftUI : DarkMode 구현하기 - Environment

서근 2021. 4. 14. 00:37
반응형

.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를 지우고 우리가 만들었던 ThememyBackgoundColor를 가져와줘야 합니다.

기본적으로 snippet이 적용되어있다.

이제 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 👇🏻

 

Seogun95/SwiftUI_DarkMode_TUT

Environment를 사용하여 다크모드 설정. Contribute to Seogun95/SwiftUI_DarkMode_TUT development by creating an account on GitHub.

github.com