i have 8 pages or data want show, and i want just 3 indiator for that.
i have 8 pages or data want show, and i want just 3 indiator for that.
import SwiftUI
struct OnBoardingModel {
let image: String
let title: String
let subTitle: String
}
struct OnBoardingView: View {
@State private var currentStep = 0
let datas = [
OnBoardingModel(image: "onboard1", title: "OnBoard1", subTitle: "OnBoard1"),
OnBoardingModel(image: "onboard1", title: "OnBoard2", subTitle: "OnBoard2"),
OnBoardingModel(image: "onboard1", title: "OnBoard3", subTitle: "OnBoard3"),
OnBoardingModel(image: "onboard1", title: "OnBoard4", subTitle: "OnBoard4"),
OnBoardingModel(image: "onboard1", title: "OnBoard5", subTitle: "OnBoard5"),
OnBoardingModel(image: "onboard1", title: "OnBoard6", subTitle: "OnBoard6"),
OnBoardingModel(image: "onboard1", title: "OnBoard7", subTitle: "OnBoard7"),
OnBoardingModel(image: "onboard1", title: "OnBoard8", subTitle: "OnBoard8")
]
var body: some View {
VStack {
TabView(selection: $currentStep) {
ForEach(0..<datas.count, id: \.self) { index in
VStack {
Image(datas[index].image)
.resizable()
.frame(width: 250, height: 250)
Text(datas[index].title)
.font(.title)
.fontWeight(.bold)
Text(datas[index].subTitle)
.font(.subheadline)
}
.tag(index)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
HStack {
ForEach(0..<datas.count, id: \.self) { index in
if index == currentStep {
Rectangle()
.frame(width: 20, height: 10)
.clipShape(RoundedRectangle(cornerRadius: 10))
.foregroundStyle(Color("hanBlue"))
} else {
Circle()
.frame(width: 10, height: 10)
.foregroundStyle(Color.gray)
}
}
}
Button(action: {
if currentStep < datas.count - 1 {
currentStep += 1
} else {
//Logic
}
}) {
Text("Continue")
}
}
}
}
#Preview {
OnBoardingView()
}
i want make the dot indicator show 3 dot. like this so user can swipe swipe until the end of data. but its only show 3 indicator.
I would put the dots in a scroll view so the animation looks smooth when going through each tab.
ScrollView(.horizontal) {
HStack {
ForEach(0..<datas.count, id: \.self) { index in
Circle()
.frame(width: index == currentStep ? 16 : 10, height: index == currentStep ? 16 : 10)
.foregroundStyle(.white.opacity(index == currentStep ? 1 : 0.5))
}
}
.padding()
.scrollTargetLayout()
}
.background(.blue, in: RoundedRectangle(cornerRadius: 30))
.frame(width: 70) // found empirically to fit 3 dots
.scrollTargetBehavior(.viewAligned)
.scrollPosition(id: Binding($currentStep), anchor: .center)
.allowsHitTesting(false) // disallow manual scrolling
Remember to also do .animation()
in the tab view to make this animated:
TabView(selection: $currentStep.animation())
Feel free to customise the dots' appearance. I tried to make it similar to the screenshot in the question.