I'm trying to build an image slideshow using Tab View with a custom Dot indicator based on UIPageControl but the dots are never displayed. Indeed the call to create the dot indicator is executed only once at the start of view creation
The images in the tabview are loaded based on the response received from an API request, which seems to be working really well but the call to create/update the PageControl that constructs the dot indicator never works after the data/count is updated. I see that it's getting called once when the view is constructed but any changes to the ObservedObject which updates the maximum Image count doesn't redraw the UIPageControl
I would like some advice to identify the issue in my code.
Thanks
This is the code that constructs the View
`
import SwiftUI
class DotIndicator: ObservableObject {
@Published var maxImages = 0
@Published var selectedImageIndex = 0
}
struct HomePageView: View {
@State var appConfigurations = AppConfigData(infoPages: [], approvals: [])
@ObservedObject var slideIndicator = DotIndicator()
var body: some View {
ZStack{
BackgroundEffect()
VStack{
NavigationBar()
Spacer().frame(height:0)
TabView{
ForEach(appConfigurations.infoPages ?? [], id: \.key){infoPage in
AsyncImage(url: URL(string: infoPage.bannerImage ?? "")){ phase in
switch phase{
case .empty:
ProgressView()
.progressViewStyle(.circular)
case .success(let image):
image.resizable()
.aspectRatio(contentMode: .fill)
case .failure:
Image("megatrends-image")
@unknown default:
EmptyView()
}
}.tag(infoPage)
.frame(width: ScreenWidth(), height: ScreenHeight() * 0.32)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.frame(width: ScreenWidth(), height: ScreenHeight() * 0.32)
.task {
appConfigurations = await getAppConfig()
slideIndicator.maxImages = appConfigurations.infoPages?.count ?? 0
slideIndicator.selectedImageIndex = 0
}
Spacer().frame(height:18)
PageControl(maxImages: $slideIndicator.maxImages, currentImage: $slideIndicator.selectedImageIndex)
Spacer().frame(height:58)
CallBackButtons()
Spacer()
CreateTicketButton()
}
}
}
}
`
And here's the code that controls the UIPageControl creation
`
import Foundation
import SwiftUI
struct PageControl: UIViewRepresentable{
@Binding var maxImages: Int
@Binding var currentImage: Int
func makeUIView(context: Context) -> UIPageControl {
print("Calling")
let control = UIPageControl()
control.backgroundStyle = .minimal
control.numberOfPages = maxImages
control.currentPage = currentImage
control.currentPageIndicatorTintColor = UIColor.blue
control.pageIndicatorTintColor = UIColor.black
control.backgroundColor = UIColor.clear
control.isUserInteractionEnabled = false
return control
}
func updateUIView(_ uiView: UIPageControl, context: Context) {
uiView.currentPage = currentImage
}
}
`