微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

更改buttonStyle以实现暗光模式

如何解决更改buttonStyle以实现暗光模式

我创建了两种中性按钮样式:DarkButtonStyle和LightButtonStyle。我想在黑暗模式下在它们之间交替。我尝试在buttonStyle配置中使用环境变量,但这根本不起作用。由于buttonStyle没有背景颜色之类的简单区别,我也不能简单地以通用方式更改填充

import SwiftUI

struct DemoView: View {
    @Environment(\.colorScheme) var colorScheme
    
    var body: some View {
        vstack {
            Button(action: {
                
            }) {
                Text("Playstation")
                    .font(.title)
                    .fontWeight(.thin)
                    .foregroundColor(.black)
            }.buttonStyle(colorScheme == .dark ? DarkButtonStyle() : LightButtonStyle())
        }
    }
}

buttonStyle修饰符:

import SwiftUI

extension Color {
    static let offWhite = Color(red: 225/255,green: 225/255,blue: 235/255)
    
    static let darkStart = Color(red: 50 / 255,green: 60 / 255,blue: 65 / 255)
    static let darkEnd = Color(red: 25 / 255,green: 25 / 255,blue: 30 / 255)
}

extension LinearGradient {
    init(_ colors: Color...) {
        self.init(gradient: Gradient(colors: colors),startPoint: .topLeading,endPoint: .bottomTrailing)
    }
}

struct DarkBackground<S: Shape>: View {
    var isHighlighted: Bool
    var shape: S

    var body: some View {
        ZStack {
            if isHighlighted {
                shape
                    .fill(LinearGradient(Color.darkEnd,Color.darkStart))
                    .overlay(shape.stroke(LinearGradient(Color.darkStart,Color.darkEnd),linewidth: 4))
                    .shadow(color: Color.darkStart,radius: 10,x: 5,y: 5)
                    .shadow(color: Color.darkEnd,x: -5,y: -5)

            } else {
                shape
                    .fill(LinearGradient(Color.darkStart,Color.darkEnd))
                    .overlay(shape.stroke(Color.darkEnd,x: -10,y: -10)
                    .shadow(color: Color.darkEnd,x: 10,y: 10)
            }
        }
    }
}

struct LightBackground<S: Shape>: View {
    var isHighlighted: Bool
    var shape: S
    
    var body: some View {
        ZStack {
            if isHighlighted {
                shape
                    .fill(Color.offWhite)
                    .overlay(
                        RoundedRectangle(cornerRadius: /*@START_MENU_TOKEN@*/25.0/*@END_MENU_TOKEN@*/,style: /*@START_MENU_TOKEN@*/.continuous/*@END_MENU_TOKEN@*/)
                            .stroke(Color.black,linewidth: 4)
                            .blur(radius: 4)
                            .offset(x: 2,y: 2)
                            .mask(RoundedRectangle(cornerRadius: /*@START_MENU_TOKEN@*/25.0/*@END_MENU_TOKEN@*/,style: /*@START_MENU_TOKEN@*/.continuous/*@END_MENU_TOKEN@*/).fill(LinearGradient(Color.black,Color.clear)))
                    )
                    .overlay(
                        RoundedRectangle(cornerRadius: /*@START_MENU_TOKEN@*/25.0/*@END_MENU_TOKEN@*/,style: /*@START_MENU_TOKEN@*/.continuous/*@END_MENU_TOKEN@*/)
                           .stroke(Color.white,linewidth: 8)
                            .blur(radius: 4)
                            .offset(x: -2,y: -2)
                            .mask(RoundedRectangle(cornerRadius: /*@START_MENU_TOKEN@*/25.0/*@END_MENU_TOKEN@*/,style: /*@START_MENU_TOKEN@*/.continuous/*@END_MENU_TOKEN@*/).fill(LinearGradient(Color.clear,Color.black)))
                    )
            } else {
                shape
                    .fill(Color.offWhite)
                    .shadow(color: Color.black.opacity(0.2),y: 10)
                    .shadow(color: Color.white.opacity(0.7),y: -5)
            }
        }
    }
}

struct DarkButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .padding(.all,40)
            .contentShape(RoundedRectangle(cornerRadius: 25.0,style: .continuous))
            .background(
                DarkBackground(isHighlighted: configuration.ispressed,shape: RoundedRectangle(cornerRadius: 25.0,style: .continuous))
            )
    }
}

struct LightButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .padding(.all,style: .continuous))
            .background(
                LightBackground(isHighlighted: configuration.ispressed,style: .continuous))
            )
    }
}

解决方法

通过以下方式将两种样式的同一按钮组合为暗和亮模式:

struct DarkOrLightBackground<S: Shape>: View {
    @Environment(\.colorScheme) var colorScheme
    var isHighlighted: Bool
    var shape: S
    
    var body: some View {
        if colorScheme == .dark {
            DarkBackground(isHighlighted: isHighlighted,shape: RoundedRectangle(cornerRadius: 25.0,style: .continuous))
        } else {
            LightBackground(isHighlighted: isHighlighted,style: .continuous))
        }
    }
}

struct DarkorLightButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .padding(.all,40)
            .contentShape(RoundedRectangle(cornerRadius: 25.0,style: .continuous))
            .background(
                DarkOrLightBackground(isHighlighted: configuration.isPressed,style: .continuous))
            )
    }
}

然后将DemoView中的buttonStyle更改为DarkorLightButtonStyle()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。