Im trying to get midX position of Button, but it always gives me unexpected result. I have tried to use .global, .local. and .named coordinate spaces but it still don't work. Maybe there is another way to get coordinates of UI element without GeometryReader The curve center should be in the center of selected button.
struct CoreTabBar: View {
@State var selectedTab: Tab = .home
@State private var xAxis: CGFloat = 0
private let home: AnyView
private let search: AnyView
private let media: AnyView
init(
home: AnyView,
search: AnyView,
media: AnyView
) {
self.home = home
self.search = search
self.media = media
}
var body: some View {
ZStack(alignment: .center) {
TabView(selection: $selectedTab) {
switch selectedTab {
case .home:
home
.ignoresSafeArea()
case .search:
search
.ignoresSafeArea()
case .media:
media
.ignoresSafeArea()
}
}
VStack {
Spacer()
HStack(spacing: 0) {
ForEach(Tab.allCases, id: \.self) { tab in
if tab == .search { Spacer(minLength: 0) }
GeometryReader { proxy in
Button {
selectedTab = tab
xAxis = proxy.frame(in: .named("TabBar")).midX
} label: {
Image(systemName: tabImage(tab))
.resizable()
.renderingMode(.template)
.aspectRatio(contentMode: .fit)
.frame(width: 25, height: 25)
.foregroundColor(tab == selectedTab ? Color.blue : Color.gray)
.coordinateSpace(name: "Button")
}
.onAppear {
}
}
.frame(width: 25, height: 25)
if tab == .search { Spacer(minLength: 0) }
}
}
.coordinateSpace(name: "TabBar")
.padding(.horizontal, 60)
.padding(.vertical)
.background(Color.white.clipShape(TabBarShape(xAxis: self.xAxis)))
.cornerRadius(50)
.padding(.horizontal, idiomIsPhone() ? nil : tabBarHorizontalPaddingForIpad())
Spacer()
.frame(height: 5)
}
}
}