Search code examples
iosbuttonswiftuigradient

How to add a gradient above button in SwiftUI that is overlapping the content? iOS 13


I have to add a gradient over the button that is showing transparency over the text above the button. The height of the button should be 60. The height of gradient should be 30, but the gradient should overlap other content in the view. Unfortunately I have to support iOS 13. enter image description here

What I have currently is displaying the gradient over the button, but the total height of the button is 60 + 30:


VStack(spacing: 0) {
           Rectangle()
               .foregroundColor(.clear)
               .background(
                   LinearGradient(
                       gradient: Gradient(colors: [.white.opacity(0.1), .white.opacity(1)]),
                       startPoint: .top,
                       endPoint: .bottom))
               .frame(height: 30)

           Button(action: {
               state.isExpanded.toggle()
           }, label: {
               Text(state.isExpanded ? "Collapse" : "Expand")
                   .frame(maxWidth: .infinity,
                          minHeight: 60,
                          maxHeight: 60,
                          alignment: .center)
                   .foregroundColor(Color(.red))
                   .background(Color(.white))
           })
               .buttonStyle(.plain)
       }


Solution

  • If it helps someone, I managed to do it with overlay.

       Button(action: {
                 state.isExpanded.toggle()
              }, label: {
                 Text(state.isExpanded ? "Collapse" : "Expand")
                       .frame(maxWidth: .infinity,
                              minHeight: 60,
                              maxHeight: 60,
                              alignment: .center)
                       .foregroundColor(Color(.red))
                       .background(Color(.white))
               }).overlay(Rectangle()
                    .foregroundColor(.clear)
                    .background(LinearGradient(
                    gradient: Gradient(colors: [.white.opacity(0), .white.opacity(1)]),
                                       startPoint: .top,
                                       endPoint: .bottom))
                              .frame(height: 30)
                              .alignmentGuide(.top) { $0[.top] + 30 },
                    alignment: .top)