How to hide shadow over curved path in TabView background shape SwiftUI

65 views Asked by At

I am trying to add a curved shape at the centre of TabView. However while applying shadow to curved path. Rectangle shadow is showing over it. I don't know what am I doing wrong. Would you please help me find out.

Following is my View's Code :

struct MainTabView: View {
    
    @State private var activeTab: Int = 0
    
    var body: some View {
        VStack {
            TabView(selection: $activeTab) {
                Text("").tag(0)
                    .toolbar(.hidden, for: .tabBar)
                Text("").tag(1)
                    .toolbar(.hidden, for: .tabBar)
                Text("").tag(2)
                    .toolbar(.hidden, for: .tabBar)
                Text("").tag(3)
                    .toolbar(.hidden, for: .tabBar)
                
            }
            CustomTabBar()
        }
    }
    
    var centerItem: some View {
        VStack {
            Image("")
                .renderingMode(.template)
                .resizable()
                .scaledToFill()
                .frame(width: 32, height: 32)
                .foregroundColor(.white)
                .background {
                    Circle().fill(.clear)
                        .frame(width: 60, height: 60)
                }
            Spacer().frame(height: 50)
        }
    }
    
    @ViewBuilder
    func CustomTabBar(_ tint: Color = .blue, _ inactiveTint: Color = .gray) -> some View {
        HStack(alignment: .bottom) {
            ForEach(0..<4) { tab in
                if tab == 2 {
                    centerItem.frame(width: 35, height: 35)
                }
                TabItem()
            }
        }
        .padding(.horizontal)
        .padding(.vertical)
        .background(content: {
            TabShape(midpoint: UIScreen.main.bounds.width/2.0)
                .fill(.white)
                .ignoresSafeArea()
                .shadow(color: tint.opacity(0.2), radius: 5, x: 0, y: -5)
                .blur(radius: 2)
                .padding(.top, 10)
        })
    }
}

struct TabItem: View {
    var body: some View {
        VStack {
            Image(systemName: "")
                .font(.title2)
                .frame(width: 30)
                .frame(height: 30)
        }
        .frame(maxWidth: .infinity)
        .contentShape(Rectangle())
    }
    
    /*
     
     */
}

struct TabShape: Shape {
    var midpoint: CGFloat
    func path(in rect: CGRect) -> Path {
        return Path { path in
            /// Rectangle shape
            path.addPath(Rectangle().path(in: rect))
            /// Bump shape
            path.move(to: .init(x: midpoint - 60, y: -10))
            
            let to = CGPoint(x: midpoint, y: -25)
            let control1 = CGPoint(x: midpoint - 30, y: 0)
            let control2 = CGPoint(x: midpoint - 30, y: -25)
            path.addCurve(to: to, control1: control1, control2: control2)
            
            let to1 = CGPoint(x: midpoint + 60, y: 0)
            let control3 = CGPoint(x: midpoint + 30, y: -25)
            let control4 = CGPoint(x: midpoint + 30, y: 0)
            path.addCurve(to: to1, control1: control3, control2: control4)
        }
    }
}

#Preview {
    MainTabView()
}

enter image description here

1

There are 1 answers

0
Benzy Neez On BEST ANSWER

If you try commenting out the shadow and changing to .stroke instead of .fill then it reveals a small problem:

TabShape(midpoint: UIScreen.main.bounds.width/2.0)
    .stroke(.blue)
//    .fill(.white)
    .ignoresSafeArea()
//    .shadow(color: tint.opacity(0.2), radius: 5, x: 0, y: -5)
//    .blur(radius: 2)
    .padding(.top, 10)

WonkyPath

So I think your TabShape needs a correction:

/// Bump shape
path.move(to: .init(x: midpoint - 60, y: 0)) // not y: -10

After this, I think the shadow works as you intended:

Fixed