SwiftUI 中的 TabBar 自定义

问题描述 投票:0回答:1

我想自定义标签栏,例如中心的弯曲矩形,但我所能做的就是在中心添加一张图像。边框应该在圆圈下方,尝试了很多方法但没有成功,希望有人能帮助我得到这个。

我尝试过:

我的期待:

标签栏视图:

struct TabBarView: View {
    
    @State var selectedTab = 0
    
    var body: some View {
        ZStack(alignment: .bottom) {
                    TabView(selection: $selectedTab) {
                        HomeView()
                            .tag(0)

                        Search()
                            .tag(1)

                        Tickets()
                            .tag(2)

                        Profile()
                            .tag(3)

                        Settings()
                            .tag(4)
                    }

                    RoundedRectangle(cornerRadius: 25)
                        .frame(width: 350, height: 70)
                        .foregroundColor(.white)
                        .shadow(radius: 0.8)

                    Button {
                        selectedTab = 2
                    } label: {
                        CustomTabItem(imageName: "ticket", title: "Ticket", isActive: (selectedTab == 2))
                    }
                    .frame(width: 65, height: 65)
                    .background(Color.white)
                    .clipShape(Circle())
                    .shadow(radius: 0.8)
                    .offset(y: -50)

                    HStack {
                        ForEach(TabbedItems.allCases, id: \.self) { item in
                            if item != .ticket { // Exclude the center button
                                Button {
                                    selectedTab = item.rawValue
                                } label: {
                                    CustomTabItem(imageName: item.iconName, title: item.title, isActive: (selectedTab == item.rawValue))
                                }
                            }
                        }
                    }
                    .frame(height: 70)
                }
            }
        }

扩展名:

extension TabBarView {
    func CustomTabItem(imageName: String, title: String, isActive: Bool) -> some View{
        HStack(alignment: .center,spacing: 22){
            Spacer()
            Image(imageName)
                .resizable()
                .renderingMode(.template)
                .foregroundColor(isActive ? .purple : .gray)
                .frame(width: 25, height: 25)
            Spacer()
        }
    }
}
swiftui tabbar rectangles rounded-corners tabview
1个回答
0
投票

您可以通过使用所需表格创建

Shape
来完成此操作。我尝试了一下,这是接近的东西:

struct TabBarShape: Shape {
    let insetRadius: CGFloat
    let cornerRadius = CGFloat(25)
    let insetCornerAngle = 45.0

    func path(in rect: CGRect) -> Path {
        var path = Path()

        // Start just below the top-left corner
        var x = rect.minX
        var y = rect.minY + cornerRadius
        path.move(to: CGPoint(x: x, y: y))

        // Add the rounded corner on the top-left corner
        x += cornerRadius
        path.addArc(
            center: CGPoint(x: x, y: y),
            radius: cornerRadius,
            startAngle: .degrees(180),
            endAngle: .degrees(270),
            clockwise: false
        )
        // Begin inset in middle, cutting into shape
        x = rect.midX - (2 * insetRadius)
        y = rect.minY + insetRadius
        path.addArc(
            center: CGPoint(x: x, y: y),
            radius: insetRadius,
            startAngle: .degrees(270),
            endAngle: .degrees(270 + insetCornerAngle),
            clockwise: false
        )
        // Add a half-circle to fit the button
        x = rect.midX
        y = rect.minY
        path.addArc(
            center: CGPoint(x: x, y: y),
            radius: insetRadius,
            startAngle: .degrees(90 + insetCornerAngle),
            endAngle: .degrees(90 - insetCornerAngle),
            clockwise: true
        )
        // Complete the inset with the second rounded corner
        x += (2 * insetRadius)
        y += insetRadius
        path.addArc(
            center: CGPoint(x: x, y: y),
            radius: insetRadius,
            startAngle: .degrees(270 - insetCornerAngle),
            endAngle: .degrees(270),
            clockwise: false
        )
        // Top-right corner
        x = rect.maxX - cornerRadius
        y = rect.minY + cornerRadius
        path.addArc(
            center: CGPoint(x: x, y: y),
            radius: cornerRadius,
            startAngle: .degrees(270),
            endAngle: .degrees(0),
            clockwise: false
        )
        // Bottom-right corner
        y = rect.maxY - cornerRadius
        path.addArc(
            center: CGPoint(x: x, y: y),
            radius: cornerRadius,
            startAngle: .degrees(0),
            endAngle: .degrees(90),
            clockwise: false
        )
        // Bottom-left corner
        x = rect.minX + cornerRadius
        path.addArc(
            center: CGPoint(x: x, y: y),
            radius: cornerRadius,
            startAngle: .degrees(90),
            endAngle: .degrees(180),
            clockwise: false
        )
        path.closeSubpath()
        return path
    }
}

然后您可以使用自定义形状代替之前使用的

RoundedRectangle

// RoundedRectangle(cornerRadius: 25)
TabBarShape(insetRadius: 30)
    .frame(width: 350, height: 70)
    .foregroundColor(.white)
    .shadow(color: Color(white: 0.8), radius: 6, x: 0, y: 3)

Button {
    selectedTab = 2
} label: {
    CustomTabItem(imageName: "ticket", title: "Ticket", isActive: (selectedTab == 2))
}
.frame(width: 50, height: 50)
.background(Color.white)
.clipShape(Circle())
.shadow(radius: 0.8)
.offset(y: -50)

这是它的外观,您可能需要稍微调整一下插图:

TabBarShape

© www.soinside.com 2019 - 2024. All rights reserved.