Search code examples
iosswiftswiftuigradientshadow

I want all side gradient shadow button in swiftUI


enter image description here

I want to achieve this kind of gradient shadow in swiftUI button. Any help or suggetion will be appreciated. I have already achieved gradient border. Thanks in advance!!


Solution

  • You could create custom ButtonStyle implementation of which may look like this one:

    struct GradientButtonStyle: ButtonStyle {
        
        private struct GradientButtonPreferenceKey: PreferenceKey {
            static var defaultValue: CGSize = .zero
            
            static func reduce(value: inout CGSize, nextValue: () -> CGSize) { }
        }
        
        @State private var buttonSize: CGSize = .zero
        
        func makeBody(configuration: Configuration) -> some View {
             configuration.label
                 .padding()
                 .background(.white)
                 .clipShape(RoundedRectangle(cornerRadius: 10))
                 .overlay {
                     GeometryReader { proxy in
                         Color.clear
                             // Getting current size of button
                             .preference(key: GradientButtonPreferenceKey.self, value: proxy.size)
                     }
                 }
                 .background {
                     Rectangle()
                     // We'll use Linear gradient with three colors I can see in your example.
                         .fill(LinearGradient(colors: [.yellow, .purple, .blue],
                                              startPoint: .leading,
                                              endPoint: .trailing))
                     // You can adjust gradient size by multilplying its value on desired factor here
                         .frame(width: buttonSize.width, height: buttonSize.height)
                     // Higher the number further from body gradient will be "sprayed".
                         .blur(radius: 30)
                     // Makes cool effect of pressing the button.
                         .opacity(configuration.isPressed ? 0.7 : 1)
                 }
                 .onPreferenceChange(GradientButtonPreferenceKey.self, perform: { value in
                     buttonSize = value
                 })
        }
    }
    

    And after usage of the style:

    Button("Custom Gradient Button") {}
        .buttonStyle(GradientButtonStyle())
    

    You get the result:

    enter image description here

    NOTE: Once gradient being blurred it is impossible(at least I don't know the way) to get the frame of the "sprayed" area, so all spacing, padding et cetera. Will be calculated from the body of the button, in this current case – white rectangle.