我想自定义标签栏,例如中心的弯曲矩形,但我所能做的就是在中心添加一张图像。边框应该在圆圈下方,尝试了很多方法但没有成功,希望有人能帮助我得到这个。
我尝试过:
我的期待:
标签栏视图:
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()
}
}
}
您可以通过使用所需表格创建
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)
这是它的外观,您可能需要稍微调整一下插图: