ios – Implementing rounded corners for toggle style twice. Once it works as expected, once it doesn’t


I am implementing two different ToggleStyles with rounded corners

The one that works correctly

extension Color {
    static let bgGradient = [
        Color(red: 60 / 255, green: 60 / 255, blue: 60 / 255),
        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)
    }
}

extension AngularGradient {
    init(_ colors:Color...) {
        self.init(colors: colors, center: .center)
    }
}

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

    var body: some View {
        ZStack {
            if isHighlighted {
                shape
                    .fill(LinearGradient(.purple, .teal))
                    .overlay(shape.stroke(AngularGradient(.teal,.purple,.teal), lineWidth: 4))
                    .shadow(color: .bgGradient.first!, radius: 10, x: 5, y: 5)
                    .shadow(color: .bgGradient.last!, radius: 10, x: -5, y: -5)
            } else {
                shape
                    .fill(LinearGradient(.bgGradient.first!, .bgGradient.last!))
                    .overlay(shape.stroke(AngularGradient(.teal,.purple,.teal), lineWidth: 4))
                    .shadow(color: .bgGradient.first!, radius: 5, x: -5, y: -5)
                    .shadow(color: .bgGradient.last!, radius: 5, x: 5, y: 5)
            }
        }
    }
}

struct RoundedRectangleGradientToggleStyle: ToggleStyle {
    var cornerSize:CGSize = CGSize(width: 10, height: 10)

    func makeBody(configuration: Self.Configuration) -> some View {
        Button(action: {
            configuration.isOn.toggle()
        }) {
            configuration.label
                .frame(minWidth: 44)
                .frame(height: 44)
                .padding(16)
                .foregroundColor(.white)
                .contentShape(RoundedRectangle(cornerSize: cornerSize))
        }
        .background(
            GradientBackground(isHighlighted: configuration.isOn, shape: RoundedRectangle(cornerSize: cornerSize))
        )
    }
}
struct NeumorphismButtons:View {
    @State private var isToggled = false

    var body: some View {
        ZStack {
            ScrollView {
                VStack(spacing: 25) {
                        
                        Toggle(isOn: $isToggled) {
                            Text("a potentially looooooooong toggle title")
                        }
                        .toggleStyle(RoundedRectangleGradientToggleStyle(cornerSize: CGSize(width: 25, height: 40)))
                        Toggle(isOn: $isToggled) {
                            Text("a potentially looooooooong toggle title")
                        }
                        .toggleStyle(RoundedRectangleGradientToggleStyle(cornerSize: CGSize(width: 40, height: 25)))
                }.padding()
            }
        }
    }
}

results in
screenshot working style

The not working one seems to use the sizes’s width value for height swell, ignoring the height value completely.

struct FrostedGlassBackground<S: Shape>: View {
    var shape: S
    var isPressed:Bool
    var body: some View {
        ZStack {
            shape
                .fill(isPressed ? .thinMaterial : .ultraThinMaterial )
        }
    }
}

struct RoundedRectangleFrostedGlassToggleStyle: ToggleStyle {
   
    var onColor: Color = .blue
    var offColor: Color = .gray
    var textColor: Color = .primary.opacity(0.5)
    var iconSize: CGFloat = 22
    var roundedCorners: CGSize = CGSize(width: 10, height: 10)
    var onIcon = Image(systemName: "checkmark.circle")
    var offIcon = Image(systemName: "circle")
    
    private func icon(isOn:Bool) -> Image {
        isOn
            ? onIcon
            : offIcon
    }
    
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            configuration.label
            Spacer()
            icon(isOn: configuration.isOn)
                .resizable()
                .foregroundColor(configuration.isOn ? onColor : offColor)
                .frame(width: iconSize, height: iconSize)
                .offset(x: -5)
        }
        .frame(minWidth: 44)
        .frame(height: 44)
        .padding(16)
        .foregroundColor(textColor)
        .contentShape(RoundedRectangle(cornerSize: roundedCorners))
        .background(
            FrostedGlassBackground(shape:RoundedRectangle(cornerSize: roundedCorners), isPressed: configuration.isOn)
        )
        .onTapGesture {
            configuration.isOn.toggle()
        }
    }
}

struct GlassmorphismButtons: View {
    @State private var isToggled = false

    var body: some View {
        ZStack {
            VStack {
                VStack {
                    Toggle(isOn: $isToggled) {
                        Text("Toggle")
                    }.toggleStyle(RoundedRectangleFrostedGlassToggleStyle(
                        onColor: .green,
                        offColor: .green,
                        roundedCorners: CGSize(width: 25, height: 40),
                        onIcon: Image(systemName: "checkmark.circle.fill"))
                    )
                    
                    Toggle(isOn: $isToggled) {
                        Text("Toggle")
                    }.toggleStyle(RoundedRectangleFrostedGlassToggleStyle(
                        roundedCorners: CGSize(width: 40, height: 25),
                        onIcon: Image(systemName: "checkmark.circle.fill"))
                    )
                }
            }.frame(minWidth:180,maxWidth: 220)
            .padding()
        }
    }
}

result:
enter image description here

What am I doing wrong? How do I need the second code to show the same corner rounding behaviour as in the first code? Thanks

the code can also be found here: https://gitlab.com/vikingosegundo/button-and-toggle-styles

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img