0

I am trying to use the PageTabview option to allow a user to move through a series of pages whose data is coming from a JSON file. I want to be able to limit the number of visible dots to 5 or 6 even if there are many values in the field. What I don't want is to have 25 dots if there are twenty-five values in the field. How would I do that? I want to be able to show indicator like an arrow that tells the user there is more to come...Thank you. My code is below:


struct TopicsExperienceCards: View {
    @Binding var closeExperience: Bool
    let etype: EItype
    var body: some View {
        //start of content of zstack layout
        ZStack {
            VStack(spacing: 20) {
                
                HStack{
                    Rectangle()
                        .fill(Color.white)
                        .frame(width: 300, height: 1, alignment: .center)
                   Spacer()
                Button(action: {
                    closeExperience = false })
                {
                Image(systemName:"xmark")
                    .foregroundColor(Color(etype.accentcolor))
                    .padding()
                }
                } //HSTACK
                TabView {
                    ForEach(etype.experience,id: \.self) { item in
                       // Display the content of a card //
                       
                       VStack (alignment:.center, spacing:0){
                                Text(item)
                                    .padding()
                                    .frame(width:300, height:300, alignment:.center)
                        Divider()
                        Spacer()
                        Text("Room for an image")
                        Spacer()
                        Spacer()
                        }//VSTACK
                        //End of display of content of the card //
                } //: FOREACH
                } //: TABVIEW
                .tabViewStyle(PageTabViewStyle())
                .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
                .onAppear {
                   setupAppearance() }
} //VSTACK

        }  //: ZStack
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
        .background(Color.white)
        .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .strokeBorder()
                        .foregroundColor(Color(etype.accentcolor)))
       .cornerRadius(16.0)
    .padding()
    }
}


struct TopicsExperienceCards_Previews: PreviewProvider {
    static let etypes: [EItype] = Bundle.main.decode("eibasestructure.json")
    static var previews: some View {
        TopicsExperienceCards(closeExperience:.constant(true),etype:etypes[1])
    }
}

enter image description here

crr-swift
  • 13
  • 5
  • just curious where the "//: ZStack" comments come from? Looks good, but I have not seen such comments much, is it from some SwiftUI tutorial? – Phil Dukhov Aug 27 '21 at 04:44
  • Thank you very much for your help Philip Dukhov. The code you added serves what I am looking for. Much appreciated. I initially did learn something like //: ZStack from a tutorial but these days I add it for my own sanity. I am not a developer but am looking to create some apps for my own personal work so find adding such comments hugely useful. Thank you again!! – crr-swift Aug 27 '21 at 13:12
  • You're welcome. If my answer solved your problem please mark it as accepted=) – Phil Dukhov Aug 27 '21 at 13:35

1 Answers1

1

System dots view is limited to around 10 dots, maybe depending on the device. You can't change this value.

Instead of that you can hide system one, and create your own view with dots. As an example you can follow this article, so at the end you'll have something like this:

@State var currentIndex = 0

var body: some View {
    //start of content of zstack layout
    ZStack {
        printUI(currentIndex)
        VStack(spacing: 20) {
            
            HStack{
                Rectangle()
                    .fill(Color.white)
                    .frame(width: 300, height: 1, alignment: .center)
                Spacer()
                Button(action: {
                        closeExperience = false })
                {
                    Image(systemName:"xmark")
                        .foregroundColor(Color.red)
                        .padding()
                }
            } //HSTACK
            TabView(selection: $currentIndex.animation()) {
                ForEach(etype.experience.indices,id: \.self) { i in
                    let item = etype.experience[i]
                    // Display the content of a card //
                    
                    VStack (alignment:.center, spacing:0){
                        Text(item)
                            .padding()
                            .frame(width:300, height:300, alignment:.center)
                        Divider()
                        Spacer()
                        Text("Room for an image")
                        Spacer()
                        Spacer()
                    }//VSTACK
                    //End of display of content of the card //
                } //: FOREACH
            } //: TABVIEW
            .tabViewStyle(PageTabViewStyle())
            .onAppear {
                setupAppearance()
            }
            Fancy3DotsIndexView(numberOfPages: etype.experience.count, currentIndex: currentIndex)
                .padding()
                .background(Color.green)
                .clipShape(Capsule())
        } //VSTACK
        
    }  //: ZStack
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
    .background(Color.white)
    .overlay(
        RoundedRectangle(cornerRadius: 16)
            .strokeBorder()
            .foregroundColor(Color.red)
    )
    .cornerRadius(16.0)
    .padding()
}

Result:

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220