更改buttonStyle以实现暗光模式

时间:2020-08-31 12:43:56

标签: swiftui

我创建了两种中性按钮样式: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, radius: 10, x: -5, y: -5)

            } else {
                shape
                    .fill(LinearGradient(Color.darkStart, Color.darkEnd))
                    .overlay(shape.stroke(Color.darkEnd, lineWidth: 4))
                    .shadow(color: Color.darkStart, radius: 10, x: -10, y: -10)
                    .shadow(color: Color.darkEnd, radius: 10, 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), radius: 10, x: 10, y: 10)
                    .shadow(color: Color.white.opacity(0.7), radius: 10, x: -5, 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, 40)
            .contentShape(RoundedRectangle(cornerRadius: 25.0, style: .continuous))
            .background(
                LightBackground(isHighlighted: configuration.isPressed, shape: RoundedRectangle(cornerRadius: 25.0, style: .continuous))
            )
    }
}

1 个答案:

答案 0 :(得分:0)

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

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, shape: RoundedRectangle(cornerRadius: 25.0, 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, shape: RoundedRectangle(cornerRadius: 25.0, style: .continuous))
            )
    }
}

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