👈
[SwiftUI] TabView のインジケータをカスタマイズする
ページングUI やページャーやタブUI と言われている、「横スワイプしてページを切り替えるUI」のインジケータをカスタマイズした話です。
困ったこと
横スワイプしてページを切り替えるUI は、SwiftUI ではTabView
とPageTabViewStyle
を利用することで実現することができます。
しかしTabView のPageTabViewStyle ではデフォルトのインジケータを表示してくれるものの、そのインジケータはほぼカスタマイズできません。
今回はインジケータの座標を変更して、任意の位置にインジケータを表示することをやりたいと思いました。
対処方法
デフォルトのインジケータを使わず、独自のインジケータUI を使うという発想になります。
以下が独自に実装したインジケータUI のコードです。
struct TabIndexView: View {
let numberOfPages: Int
let currentIndex: Int
var dotSize = CGFloat(5)
var spacing = CGFloat(6)
var dotColor = Color.white
var borderColor = Color.white
var body: some View {
HStack(spacing: spacing) {
ForEach(0..<numberOfPages) { index in
if index == currentIndex {
Circle()
.fill(dotColor)
.frame(width: dotSize, height: dotSize)
} else {
Circle()
.stroke(borderColor, lineWidth: 0.5)
.frame(width: dotSize, height: dotSize)
}
}
}
}
}
次のコードで実装したインジケータを利用します。
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
によってデフォルトのインジケータUI を非表示にしています。
また、.overlay
のところで任意のpadding を与えることによって、インジケータが表示される位置を調整しています。
@State private var currentTabViewIndex = Int(0)
var content: some View {
TabView(selection: $currentTabViewIndex) {
pageView
.tag(0)
pageView
.tag(1)
pageView
.tag(2)
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.overlay(
VStack {
Spacer()
TabIndexView(numberOfPages: 3, currentIndex: currentTabViewIndex)
.padding(.bottom, 44)
}
)
}
独自のUI のため、もちろんドットなどの見た目も自由に変更することができます。
末尾の参考記事のようにアニメーションを付けたりすると格好いいかもしれません。
Discussion