Reputation: 533
Is there a way to change the tabView Indicator color in swiftUI ?
This is my code
struct OnBoarding: View {
var body: some View {
TabView {
ForEach(0 ..< 3) { item in
VStack {
Image("discover")
.resizable()
.scaledToFit()
}
}
}
.tabViewStyle(PageIndexViewStyle(backgroundDisplayMode: Color ?))
}
}
struct OnBoarding_Previews: PreviewProvider {
static var previews: some View {
OnBoarding()
}
}
I tried tabViewStyle(PageIndexViewStyle(backgroundDisplayMode: Color ?))
, but can't get around with it.
Upvotes: 33
Views: 22502
Reputation: 1250
Needed to do this, this morning and decided to whip up a ViewModifier
. The benefit of this approach is it sets it back to the previous value once the tab view disappears.
To use:
TabView {
// ...
}
.tintedTabViewStyle()
The Modifier:
import SwiftUI
extension View {
func tintedTabViewStyle(_ pageTabViewStyle: PageTabViewStyle = .page, color: Color = .accentColor) -> some View {
self.modifier(TintedPageViewTabStyleModifier(pageTabViewStyle: pageTabViewStyle, color: color))
}
}
struct TintedPageViewTabStyleModifier: ViewModifier {
var pageTabViewStyle: PageTabViewStyle
var color: Color
@State private var originalCurrentPageIndicatorTintColor: UIColor?
@State private var originalPageIndicatorTintColor: UIColor?
func body(content: Content) -> some View {
content
.tabViewStyle(pageTabViewStyle)
.onAppear {
let appearance = UIPageControl.appearance()
originalCurrentPageIndicatorTintColor = appearance.currentPageIndicatorTintColor
originalPageIndicatorTintColor = appearance.pageIndicatorTintColor
appearance.currentPageIndicatorTintColor = UIColor(color)
appearance.pageIndicatorTintColor = UIColor(color.opacity(0.2))
}
.onDisappear {
guard let originalCurrentPageIndicatorTintColor,
let originalPageIndicatorTintColor else { return }
let appearance = UIPageControl.appearance()
appearance.currentPageIndicatorTintColor = originalCurrentPageIndicatorTintColor
appearance.pageIndicatorTintColor = originalPageIndicatorTintColor
}
}
}
Upvotes: 0
Reputation: 554
If you simply don't want to mess with UIKit on SwiftUI, or you need to give the color after init:
Create your own! and have total style control
@State private var tabSelection = 0
var body: some View {
ZStack(alignment:.bottom){
TabView(selection: $tabSelection.animation()){
Text("Slide 1")
.frame(maxWidth: .infinity)
.tag(0)
Text("Slide 2")
.frame(maxWidth: .infinity)
.tag(1)
Text("Slide 3")
.frame(maxWidth: .infinity)
.tag(2)
}
.aspectRatio(1, contentMode: .fit)
.frame(maxWidth: .infinity)
.tabViewStyle(.page(indexDisplayMode: .never))
HStack(spacing: 6){
ForEach(0..<3) { i in
Image(systemName: "circle.fill")
.font(.system(size: 9))
.foregroundStyle(tabSelection == i ? .black : .gray)
}
}
.padding(.bottom)
}
}
Upvotes: 6
Reputation: 145
If you are using SwiftUI from UIKit there's a more delicate way to update UIPageControl appearance.
// SwiftUI with with UIPageControl
struct MyView: View { ... }
import SwiftUI
import UIKit
final class MyViewContainerController: UIHostingController<MyView> {
init() {
let view = MyView()
super.init(rootView: view)
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
let containerTypes = [MyViewContainerController.self]
let appearance = UIPageControl.appearance(whenContainedInInstancesOf: containerTypes)
appearance.currentPageIndicatorTintColor = .systemBlue
appearance.pageIndicatorTintColor = .systemIndigo
}
}
Upvotes: 6
Reputation: 639
First create a subview like:
struct SliderTabView: View {
init() {
UIPageControl.appearance().currentPageIndicatorTintColor = .red
UIPageControl.appearance().pageIndicatorTintColor = UIColor.red.withAlphaComponent(0.2)
}
var body: some View {
TabView{
ForEach(players){ player in
//Slider content here ...
}
}.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
}
Call the subview from main view like:
struct ContentView: View {
var body: some View {
SliderTabView()
}
}
Upvotes: 6
Reputation: 1533
Basically you need to set the global variable when your view appears. One way to do it is as follows:
import SwiftUI
struct OnboardingView: View {
var pages: [Page]
var body: some View {
TabView {
ForEach(pages) { page in
// Your component view
}
}
.tabViewStyle(PageTabViewStyle())
.onAppear {
setupAppearance()
}
}
func setupAppearance() {
UIPageControl.appearance().currentPageIndicatorTintColor = .black
UIPageControl.appearance().pageIndicatorTintColor = UIColor.black.withAlphaComponent(0.2)
}
}
Upvotes: 29
Reputation: 1520
you need to use UIkit
init() {
UIPageControl.appearance().currentPageIndicatorTintColor = .red
UIPageControl.appearance().pageIndicatorTintColor = UIColor.black.withAlphaComponent(0.2)
}
Upvotes: 58