SwiftUI 的换肤功能
2023-03-16 本文已影响0人
激动的厨师
如图:
[图片上传失败...(image-116cfb-1679038440320)]
因为老项目突然要加上一键换肤,做完老项目后,抽空用SwifUI 再实现一遍,感觉上要比UIkit框架要简单的多了。不多说上代码:
首先定义一个枚举Theme, 里面实现一些方法
enum SFAppTheme: String{
case Red_APP_Theme = "red"
case Blue_APP_Theme = "blue"
case Green_APP_Theme = "green"
case Yellow_APP_Theme = "yellow"
func homeBg() -> String {
switch self {
case .Red_APP_Theme:
return "bg04"
case .Blue_APP_Theme:
return "bg01"
case .Green_APP_Theme:
return "bg02"
case .Yellow_APP_Theme:
return "bg03"
}
}
func setPageBg() -> String {
switch self {
case .Red_APP_Theme:
return "set_bg04"
case .Blue_APP_Theme:
return "set_bg01"
case .Green_APP_Theme:
return "set_bg02"
case .Yellow_APP_Theme:
return "set_bg03"
}
}
func themeColor() -> Color {
switch self {
case .Red_APP_Theme:
return Color("AppRed")
case .Blue_APP_Theme:
return Color("AppBlue")
case .Green_APP_Theme:
return Color("AppGreen")
case .Yellow_APP_Theme:
return Color("AppYellow")
}
}
static func nowTheme() -> SFAppTheme {
guard let theme:String = UserDefaults.standard.string(forKey: "SFAppThemeKey") else{
return .Red_APP_Theme
}
guard let nowThemeType = SFAppTheme(rawValue: theme) else{
return .Red_APP_Theme
}
return nowThemeType
}
}
然后定义一个APPState 用来存储app的状态值所用:
class APPState:ObservableObject{
@Published var appTheme:SFAppTheme = .Red_APP_Theme
init() {
//创建imei
let sfDevice = SFDevice()
sfDevice.creatImei()
appTheme = SFAppTheme.nowTheme()
}
func setTheme(theme:SFAppTheme){
UserDefaults.standard.setValue(theme.rawValue, forKey: "SFAppThemeKey")
self.appTheme = theme
}
}
最后再app入口地方注入:
@main
struct seaSoftDRPSwiftUiApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@StateObject var appState:APPState = APPState() //APP的全局状态 可以切换主题啥的 environmentObject注入到全局中
var body: some Scene {
WindowGroup {
LaunchView()
.environmentObject(appState)
}
}
}
用的时候:
@EnvironmentObject var appState:APPState
.background(
appState.appTheme.themeColor()
.frame(width: screenWidth)
.ignoresSafeArea(.all,edges: .top)
)
Button {
appState.setTheme(theme: .Red_APP_Theme)
} label: {
Text("切换主题红色")
}
这样即可实现一键换肤,
需要注意这里的定义Color因为要适配黑暗模式,是在Assets里自己添加的Color Set 如下图:
[图片上传失败...(image-406ab1-1679038440320)]
如果也需要修改纯色图片,那么可以让UI给你一个SVG图片,然后在 Assets里设置图片的RenderModel为
Template Image。就可以直接用 :foregroundColor 直接给图片着色
[图片上传失败...(image-2010f5-1679038440320)]
Image(type.barName())
.resizable()
.frame(width: 25,height: 25)
.foregroundColor(viewModel.selectedTab == type ? appState.appTheme.themeColor() : Color(hex: "999999"))
如果不是纯色图片,就麻烦点,我这里有个就是不是纯色图片,用的枚举返回的,上诉代码里的:
func setPageBg() -> String {
switch self {
case .Red_APP_Theme:
return "set_bg04"
case .Blue_APP_Theme:
return "set_bg01"
case .Green_APP_Theme:
return "set_bg02"
case .Yellow_APP_Theme:
return "set_bg03"
}
}
希望能帮到纠结的小伙伴~