Tom
Tom

Reputation: 23

SwiftUI styling (List color & UIPageControl height)

Dears,

given the following View :

import SwiftUI
import WebKit

var regions = ["Bayern","Brandenburg","Hamburg","Hessen","Saarland"]
var tabs = ["home","menu_book","photo","audio","movie","view_cozy"]

struct ContentView: View {
    
    @State var selectedRegion: Int = 0
    
    var body: some View {
        NavigationView{
            ScrollView(.horizontal, showsIndicators: true) {
                        LazyHStack {
                            PageView().padding(0)
                        }
            }
            .navigationBarTitleDisplayMode(.inline)
            .toolbar{
                ToolbarItem(placement: .navigationBarLeading) {
                    Text("MyApp")
                }
                ToolbarItem(placement: .principal) {
                    Button(action:{},label :{Text("Mail")})
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Picker("Select", selection: $selectedRegion) {
                        ForEach(regions, id: \.self) { region in
                            Text(region)
                        }
                    }
                    .pickerStyle(MenuPickerStyle())
                }
            }
        }
    }
}

struct PageView: View {
    
    var body: some View {
        
        TabView {
//            Button(action: {},label: {Text("Test Button")})
            Image("home")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .padding(0)
                .frame(width:20,height: 20)
                .border(Color.blue)
            ForEach(tabs, id: \.self) { tab in
                List {
                    ForEach(0..<20) { btn in
                        Button(
                            action: {
                                print("Button clicked : Tab\(tab)_btn_\(btn)")
                        },
                            label: {
                            Text("Tab\(tab)_btn_\(btn)").font(.system(size: 12))
                        })
                        .background(SwiftUI.Color.pink)
                    }
                }
                .background(SwiftUI.Color.yellow)
                .tabItem {
                    Image(tab)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(0)
                        .frame(width:20,height: 20)
                        .border(Color.blue)
//                    Text(tab)
                }
            }
        }
        .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        .tabViewStyle(PageTabViewStyle())
        .background(SwiftUI.Color.orange)
    }
    
    init() {
        UIPageControl.appearance().currentPageIndicatorTintColor = .red
        UIPageControl.appearance().pageIndicatorTintColor = .blue
        UIPageControl.appearance().backgroundColor = .green
//        UIPageControl.appearance().transform = CGAffineTransform.init(scaleX: 0.8, y: 0.8)
        
//        UITabBar.appearance().barTintColor = .orange
    }
}

I would like to be able to set the background color of my list to a specific color (let's say orange) and reduce the height of the page indicator (that bar on the bottom which has the all the icons).

what I've tried you can see in the code comments. Anyway, whatever I do I end up with the following view : enter image description hereenter image description here The idea would be that on the second tab (the one with the home icon) the list background should have the same background color as on the first tab. The icons are SVG (at least that's what I've imported in Xcode). How can I reduce the size of that bottom bar ? (Icons seem too big)

Thanks for any tips.

Upvotes: 0

Views: 234

Answers (1)

Benzy Neez
Benzy Neez

Reputation: 21730

I had quite a bit of difficulty getting your code to run in a way that looked anything like your screenshots using an iPhone 14 simulator and iOS 17. These changes helped:

  1. Remove the ScrollView and LazyHStack around PageView:
NavigationView {
//    ScrollView(.horizontal, showsIndicators: true) {
//        LazyHStack {
            PageView() //.padding(0)
//        }
//    }
  1. Don't set the frame width and height using UIScreen.main.bounds (which is deprecated anyway).
//    .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)

  1. Turn the home page into a full page by wrapping with a ZStack, using a color to fill all the space available:
ZStack {
    SwiftUI.Color.orange
    Image("home")
        .resizable()
        .aspectRatio(contentMode: .fit)
        // .padding(0)
        .frame(width:20, height: 20)
        .border(Color.blue)
}

This way, you don't need to set a background on the TabView, which means the navigation bar does not get an orange background.

//    .background(SwiftUI.Color.orange)

The console was also reporting a problem with the Picker, because:

the selection "0" is invalid and does not have an associated tag

but I didn't try to fix this.

So with the changes above, it looked like this (using improvised images):

HomeOrange

What's interesting, is that the images in the tab bar are tiny and the height of the bar itself is also pretty minimal. I am using standard system images and actually, I couldn't find a way to make them bigger. So maybe you need to try re-sizing the natural size of your .svg icons. Otherwise, I don't think you have much control over the way the page indicators are shown.

You get bigger images if you use .tabViewStyle(.automatic), but only 3 images are actually shown, the rest are in a "More..." menu:

AutomaticTabBar

As for the backgrounds to the lists, you can set a background color for the list rows using .listRowBackground and you can hide the gray background of the List using .scrollContentBackground(.hidden). When these changes are all combined, the List items look like this:

List {
    ForEach(0..<20) { btn in
        // content as before
    }
    .listRowBackground(Color.yellow)
}
.scrollContentBackground(.hidden)
.background(Color.yellow)

YellowList

Here is the fully adapted code that I ended up with, in case it's useful for reference.

struct PageView: View {
//    let tabs = ["home","menu_book","photo","audio","movie","view_cozy"]
    let tabs = ["house.fill", "book.fill", "photo", "headphones", "film", "fireplace"]

    var body: some View {

        TabView {
//            Button(action: {},label: {Text("Test Button")})
            ZStack {
                SwiftUI.Color.orange
                Image(systemName: "house.fill")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .padding(0)
                    .frame(width:20, height: 20)
                    .border(Color.blue)
            }
            ForEach(tabs, id: \.self) { tab in
                List {
                    ForEach(0..<20) { btn in
                        Button(
                            action: {
                                print("Button clicked : Tab\(tab)_btn_\(btn)")
                            },
                            label: {
                                Text("Tab\(tab)_btn_\(btn)").font(.system(size: 12))
                            })
                        .background(SwiftUI.Color.pink.opacity(0.2))
                    }
                    .listRowBackground(Color.yellow)
                }
                .scrollContentBackground(.hidden)
                .background(SwiftUI.Color.yellow)
                .tabItem {
                    Image(systemName: tab)
                        .resizable()
                        .scaledToFit()
//                        .aspectRatio(contentMode: .fit)
                        .frame(width: 50, height: 50)
                        .border(Color.blue)
//                    Text(tab)
                }
            }
        }
        .tabViewStyle(.page)
    }

    init() {
        UIPageControl.appearance().currentPageIndicatorTintColor = .red
        UIPageControl.appearance().pageIndicatorTintColor = .blue
        UIPageControl.appearance().backgroundColor = .green
//        UIPageControl.appearance().transform = CGAffineTransform.init(scaleX: 0.8, y: 0.8)

//        UITabBar.appearance().barTintColor = .orange
    }
}

struct ContentView: View {
    let regions = ["Bayern", "Brandenburg", "Hamburg", "Hessen", "Saarland"]

    @State var selectedRegion: Int = 0

    var body: some View {
        NavigationView {
            PageView()
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Text("MyApp")
                    }
                    ToolbarItem(placement: .principal) {
                        Button {} label: {
                            Text("Mail")
                        }
                    }
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Picker("Select", selection: $selectedRegion) {
                            ForEach(regions, id: \.self) { region in
                                Text(region)
                            }
                        }
                        .pickerStyle(MenuPickerStyle())
                    }
                }
        }
    }
}

Hope you find something useful in all that.

Upvotes: 0

Related Questions