Update the Color Theme | SwiftUI Crypto App #26
CryptoApp: Color Scheme
구현 목표
- 앱이 제공하는 컬러 스킴을 통한 라이트/다크 모드 지원
구현 태스크
- 백그라운드, 네비게이션 뷰, 백버튼 뷰의 컬러 스킴 커스텀
- iOS 16 이슈
핵심 코드
extension Color {
static let theme = ColorTheme2()
static let launch = LaunchTheme()
}
struct ColorTheme2 {
let accent = Color.blue
let background = Color.black
let green = Color.green
let red = Color.red
let secondaryText = Color.secondary
}
Asset
에서 직접 색을 커스텀할 수도 있지만 현재 컬러 사용 방법은 static
으로 선언한 뒤 Color
로 직접 접근 중
static let theme
에 어떤 값을 주는지에 따라 교체 원활
private var allCoinsList: some View {
List {
ForEach(viewModel.allCoins) { coin in
CoinRowView(coin: coin, showHoldingsColumn: false)
.listRowInsets(.init(top: 10, leading: 0, bottom: 0, trailing: 10))
.listRowBackground(Color.theme.background)
.onTapGesture {
segue(coin: coin)
}
}
}
.listStyle(.plain)
}
- 각 리스트의 백그라운드 컬러를
accent
컬러로 커스텀
ScrollView {
VStack(alignment: .leading, spacing: 0) {
SearchBarView(searchText: $viewModel.searchText)
coinLogoList
if selectedCoin != nil {
portfolioInputSection
}
}
}
.background(
Color.theme.background
.ignoresSafeArea()
)
init() {
UITableView.appearance().backgroundColor = .clear
UINavigationBar.appearance().tintColor = UIColor(Color.theme.accent)
}
- 리스트 뷰 백그라운드 컬러 커스텀
- 네비게이션 백버튼의 틴트 컬러 터스텀 → iOS 16 이후부터는 지원되지 않는 이슈 발견
- 앱 전체의
accent
컬러가 자동으로 백버튼의 틴트 컬러로 적용, iOS 15 버전까지 네비게이션 바 틴트 컬러 오버라이드 사용이 적용 X
private func setNavigationBarTintColor() {
guard let customChevronLeftImage = UIImage(systemName: "chevron.backward")?.withTintColor(UIColor(Color.theme.accent), renderingMode: .alwaysOriginal) else { return }
UINavigationBar.appearance().backIndicatorImage = customChevronLeftImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = customChevronLeftImage
UIBarButtonItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor(Color.theme.accent)], for: .normal)
UIBarButtonItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor(Color.theme.accent)], for: .highlighted)
}
- 백버튼 이미지를 화살표 커스텀 뷰로 준 뒤 색상 커스텀을
UIBarButtonItem
에 직접 오버라이드
Reference
if #available(iOS 16.0, *) {
setNavigationBarTintColor()
}
- 위의 커스텀 함수를 iOS 16 이상에서만 적용하도록 구현
구현 화면