forrest
forrest

Reputation: 10972

How do I style Text in SwiftUI Picker View?

I have a time picker in SwiftUI and any modification that I apply to the Text values in the picker are ignored. How do I do this correctly? I am using Xcode 13 on Big Sur.

Here is the result without any modification:

Timer picker

I want the times to be larger and white so I added .font() and .foregroundColor() modifiers. Here is my code:

struct TimerPicker: View {
    @Binding var customTime: CustomTime
    
    var body: some View {
        GeometryReader { geometry in
            HStack (spacing: 0.0){
                VStack {
                    Picker(selection: self.$customTime.selectedHour, label: Text("Hrs")) {
                        ForEach(0..<24) { hour in
                            Text("\(hour) hrs")
                                .foregroundColor(.white)
                                .font(.title3)
                        }
                    }
                }
                .frame(width: geometry.size.width * 0.33)
                .clipped()
                
                VStack {
                    Picker(selection: self.$customTime.selectedMin, label: Text("Min")) {
                        ForEach(0..<61) { min in
                            Text("\(min) min")
                                .foregroundColor(.white)
                                .font(.title3)
                        }
                    }
                }
                .frame(width: geometry.size.width * 0.33)
                .clipped()
                
                VStack {
                    Picker(selection: self.$customTime.selectedSecond, label: Text("Sec")) {
                        ForEach(0..<61) { sec in
                            Text("\(sec) sec")
                                .foregroundColor(.white)
                                .font(.title3)
                        }
                    }
                }
                .frame(width: geometry.size.width * 0.33)
                .clipped()
                .transition(.scale)
            }
        } //: Geometry
    }
}

There is no change in the styling of the picker values. What is the correct way to do this?

Upvotes: 1

Views: 3143

Answers (1)

Your code seems to work for me, although I made the following small modifications. This is the code that works for me: (note there is no 60 min or 60 sec)

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State var customTime = CustomTime()
    
    var body: some View {
        Spacer()
        TimerPicker(customTime: $customTime)
        Spacer()
    }
}

struct CustomTime: Identifiable, Hashable {
    let id = UUID()
    var selectedHour = 0
    var selectedMin = 0
    var selectedSecond = 0
}

struct TimerPicker: View {
    @Binding var customTime: CustomTime
    
    var body: some View {
        GeometryReader { geometry in
            HStack (spacing: 0.0){
                VStack {
                    Picker(selection: $customTime.selectedHour, label: Text("Hrs")) {
                        ForEach(0..<24) { hour in
                            Text("\(hour) hrs").tag(hour) // <--- tag
                                .foregroundColor(.white)
                                .font(.title3)
                        }
                    }
                }
                .frame(width: geometry.size.width * 0.33)
                .clipped()
                
                VStack {
                    Picker(selection: $customTime.selectedMin, label: Text("Min")) {
                        ForEach(0..<60) { min in  // <--- only to 59
                            Text("\(min) min").tag(min) // <--- tag
                                .foregroundColor(.white)
                                .font(.title3)
                        }
                    }
                }
                .frame(width: geometry.size.width * 0.33)
                .clipped()
                
                VStack {
                    Picker(selection: $customTime.selectedSecond, label: Text("Sec")) {
                        ForEach(0..<60) { sec in  // <--- only to 59
                            Text("\(sec) sec").tag(sec) // <--- tag
                                .foregroundColor(.white)
                                .font(.title3)
                        }
                    }
                }
                .frame(width: geometry.size.width * 0.33)
                .clipped()
                .transition(.scale)
            }
            .pickerStyle(.wheel)    // <--- here
            .background(Color.red)  // <--- here
        } //: Geometry
    }
}

Upvotes: 2

Related Questions