I cannot center the indicator on which the page is located. I cannot ignore the views on the left and right. When the number of page increases, it is inevitable that the indicator of the page I am on will shift to the left when the indicator number on the right is more than the indicator number on the left.
struct OnboardingView: View {
var pages: [Page] = [
Page(page: PageOne()),
Page(page: PageTwo()),
Page(page: PageThree()),
]
@State var offset: CGFloat = 0
var body: some View {
ScrollView(.init()) {
TabView {
ForEach(pages.indices, id: \.self) { item in
if item == 0 {
AnyView(_fromValue: pages[item].page)
.overlay(
GeometryReader { proxy -> Color in
let minX = proxy.frame(in: .global).minX
DispatchQueue.main.async {
withAnimation(.default) {
self.offset = -minX
}
}
return Color.clear
}
.frame(width: 0, height: 0)
,alignment: .leading
)
} else {
AnyView(_fromValue: pages[item].page)
}
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.overlay(
HStack(spacing: 15) {
ForEach(pages.indices, id: \.self) { item in
ZStack {
Capsule()
.foregroundColor(Color.white)
.frame(width: getCurrentPageIndex() == item ? 20 : 7, height: 20)
.frame(maxWidth: getCurrentPageIndex() == item ? .infinity : nil, alignment: .center)
}
}
}
.padding(.horizontal)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
.padding(.bottom, 10)
,alignment: .bottom
)
}
.ignoresSafeArea()
}
func getCurrentPageIndex() -> Int {
let index = Int(round(Double(offset / getScreenWidth())))
return index
}
func getOffset() -> CGFloat {
let progress = offset / getScreenWidth()
return 22 * progress
}
}
struct OnboardingView_Previews: PreviewProvider {
static var previews: some View {
OnboardingView()
}
}
struct Page: Identifiable {
var id = UUID()
var page: Any
}
extension View {
func getScreenWidth() -> CGFloat {
return UIScreen.main.bounds.width
}
}
.overlay(
HStack(spacing: 15) {
ForEach(pages.indices, id: \.self) { item in
ZStack {
Capsule()
.foregroundColor(Color.white)
.frame(width: getCurrentPageIndex() == item ? 20 : 7, height: 20)
}
}
}
.padding(.horizontal)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
.padding(.bottom, 10), alignment: .bottom
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.