I want only to get Int day from a date.
ScrollView(.horizontal) {
HStack(spacing: 60) {
ForEach(steps, id: \.id) { day in
Text(day.date, style: .date)
.onTapGesture {
selectedDay = day
}
}
}
}
With this code, I get the date as November 5, 2020, but I only need 5 from all date.
struct Step: Identifiable {
let id = UUID()
let count: Int
let date: Date
let wc: Double
}
I assume you wanted something like this
ForEach(steps, id: \.id) { day in
Text("\(Calendar.current.dateComponents([.day], from: day.date).day!)")
.onTapGesture {
selectedDay = day
}
}
Related
I'm pretty new at swift coding and I'm trying to do a very simple project: just a clock that shows the time. I'm using TimelineView to refresh the time every second, but it's not working. This is my code:
import SwiftUI
struct ContentView: View {
#State var hour: Int = Calendar.current.component(.hour, from: Date())
#State var minute: Int = Calendar.current.component(.minute, from: Date())
#State var second: Int = Calendar.current.component(.second, from: Date())
var body: some View {
ZStack {
VStack{
Spacer()
HStack {
TimelineView(.periodic(from: .now, by: 1)) { timeline in
Text(String(hour))
Text(String(minute))
Text(String(second))
}
}
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.previewInterfaceOrientation(.portrait)
}
}
}
Since my hour, minute and second variables are #State and I'm using the TimelineView, they should refresh every second, shouldn't they?
I'm very confused and I would appreciate some help. Thank you very much.
You have to observe changes in the timeline.
Here I used onChange and update the value of min, sec, and hour.
struct TimerView: View {
var date: Date
#State var hour: Int = Calendar.current.component(.hour, from: Date())
#State var minute: Int = Calendar.current.component(.minute, from: Date())
#State var second: Int = Calendar.current.component(.second, from: Date())
var body: some View {
VStack {
Text(String(hour))
Text(String(minute))
Text(String(second))
}
.onChange(of: date) { _ in
second += 1
if second > 59 {
minute += 1
second = 0
if minute > 59 {
hour += 1
minute = 0
if hour > 23 {
hour = 0
}
}
}
}
}
}
struct ContentView: View { var body: some View {
ZStack {
VStack{
Spacer()
HStack {
TimelineView(.periodic(from: .now, by: 1)) { timeline in
TimerView(date: timeline.date)
}
}
Spacer()
}
}
}
}
As the documentation says (https://developer.apple.com/documentation/swiftui/timelineview):
A timeline view acts as a container with no appearance of its own. Instead, it redraws the content it contains at scheduled points in time
The content it contains is defined in the closure you provide:
TimelineView(...) { timeline in
// content which gets redrawn
}
Inside this closure you have access to a TimelineView.Context (https://developer.apple.com/documentation/swiftui/timelineview/context). With the help of this context, you can access the date which triggered the update / redraw like so:
TimelineView(.periodic(from: .now, by: 1)) { timeline in
Text("\(timeline.date)")
}
This will produce the following output:
To improve formatting, you could use a DateFormatter (https://developer.apple.com/documentation/foundation/dateformatter):
struct ContentView: View {
private let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .none
dateFormatter.timeStyle = .medium
return dateFormatter
}()
var body: some View {
TimelineView(.periodic(from: .now, by: 1)) { timeline in
Text("\(dateFormatter.string(from: timeline.date))")
}
}
}
Just make your hour-minute-second as computed property not #State
struct ContentView: View {
var hour: Int {
Calendar.current.component(.hour, from: Date())
}
var minute: Int {
Calendar.current.component(.minute, from: Date())
}
var second: Int {
Calendar.current.component(.second, from: Date())
}
var body: some View {
TimelineView(.periodic(from: .now, by: 1.0)) { timeline in
HStack {
Text(String(hour))
Text(String(minute))
Text(String(second))
}
}
}
}
Hello I have two date picker one only for date and another for hour and minute
if(showStartDatePicker) {
DatePicker("Seleziona data", selection: $selectedStartDate,/* in: startingDate...endingDate,*/ displayedComponents: [.date])
.datePickerStyle(.graphical)
} else if(showStartTimePicker) {
DatePicker("Select a date", selection: $selectedStartTime, displayedComponents: [.hourAndMinute])
.datePickerStyle(.wheel)
}
I need to obtain a single date that is the merge of the two date picker
So how can I do?
Just share the variable instead of having 2
struct DoubleDatePickerView: View {
#State var showStartDatePicker: Bool = false
#State var selectedStartDate: Date = Date()
var body: some View {
VStack{
Text(selectedStartDate.description)
if(showStartDatePicker) {
DatePicker("Seleziona data", selection: $selectedStartDate,/* in: startingDate...endingDate,*/ displayedComponents: [.date])
.datePickerStyle(.graphical)
Button("show time picker", action: {
showStartDatePicker.toggle()
})
} else {
DatePicker("Select a date", selection: $selectedStartDate, displayedComponents: [.hourAndMinute])
.datePickerStyle(.wheel)
Button("show date picker", action: {
showStartDatePicker.toggle()
})
}
}
}
}
The other option is to combine the desired components from each variable
var combined: Date{
let timeComponents: DateComponents = Calendar.current.dateComponents([.hour,.minute,.second,.timeZone], from: selectedStartTime)
let dateComponents: DateComponents = Calendar.current.dateComponents([.year,.month,.day], from: selectedStartDate)
let combined: DateComponents = .init(calendar: .current, timeZone: timeComponents.timeZone, year: dateComponents.year, month: dateComponents.month, day: dateComponents.day, hour: timeComponents.hour, minute: timeComponents.minute, second: timeComponents.second)
return Calendar.current.date(from: combined) ?? Date()
}
I have built an iOS app for the first time on my own. It’s a wage calculation app. Instead of entering total workdays in a text field, I want to select start date and end date of a period, select my day-off day, select public holiday dates, and I want to get total basic workdays minus days-off and public holidays calculated for me. How do I get a list/array of dates for a selected day within a date range? I've attached the code for my app. `
import SwiftUI
struct ContentView: View {
#State private var basicDays = ""
#State private var lateEntry = ""
#State private var absentDays = ""
#State private var otHours = ""
#State private var midNights = ""
#State private var nightShifts = ""
#State private var medAllowance = ""
#State private var dayOffOTHours = ""
#State private var pHolidayBasicHours = ""
#State private var pHolidayOTHours = ""
var netWage: Double {
let monthlyBasic = 1200.00
let dailyRate = monthlyBasic / 26
let hourlyRate = dailyRate / 8
let otRate = hourlyRate * 1.5
let dayOffRate = hourlyRate * 2
let publicHolidayRate = hourlyRate * 2
let publicHolidayOTRate = hourlyRate * 3
let basicDaysAmount = dailyRate * (Double(basicDays) ?? 0)
let lateEntryAmount = hourlyRate * (Double(lateEntry) ?? 0)
let absentDaysAmount = dailyRate * (Double(absentDays) ?? 0)
let midNightAmount = 10 * (Double(midNights) ?? 0)
let nightShiftAmount = 15 * (Double(nightShifts) ?? 0)
let dayOffOTAmount = dayOffRate * (Double(dayOffOTHours) ?? 0)
let publicHolidayAmount = (publicHolidayRate * (Double(pHolidayBasicHours) ?? 0)) + (publicHolidayOTRate * (Double(pHolidayOTHours) ?? 0))
let totalOTAmount = otRate * (Double(otHours) ?? 0)
let holidayOTAmount = dayOffOTAmount + publicHolidayAmount
let otAmount = totalOTAmount + holidayOTAmount
let totalDeduction = lateEntryAmount + absentDaysAmount
let allowances = midNightAmount + nightShiftAmount
let totalWage = basicDaysAmount + allowances + otAmount
let netWage = totalWage - totalDeduction
return netWage
}
var body: some View {
NavigationView {
Form {
Group {
Section(header: Text("Enter number of basic days")) {
TextField("", text: $basicDays)
.keyboardType(.numberPad)
}
Section(header: Text("Enter late entries in hours")) {
TextField("", text: $lateEntry)
.keyboardType(.decimalPad)
}
Section(header: Text("Enter number of days absent")) {
TextField("", text: $absentDays)
.keyboardType(.numberPad)
}
Section(header: Text("Enter number of OT hours worked")) {
TextField("", text: $otHours)
.keyboardType(.numberPad)
}
Section(header: Text("Enter number of Mid nights worked")) {
TextField("", text: $midNights)
.keyboardType(.numberPad)
}
Section(header: Text("Enter number of night shifts worked")) {
TextField("", text: $nightShifts)
.keyboardType(.numberPad)
}
Section(header: Text("Enter medical bill amount")) {
TextField("", text: $medAllowance)
.keyboardType(.decimalPad)
}
Section(header: Text("Enter number of hours worked on days-off")) {
TextField("", text: $dayOffOTHours)
.keyboardType(.numberPad)
}
Section(header: Text("Enter number of public holidays worked in total hours")) {
TextField("", text: $pHolidayBasicHours)
.keyboardType(.numberPad)
}
Section(header: Text("Enter number of OT hours worked on public holidays")) {
TextField("", text: $pHolidayOTHours)
.keyboardType(.numberPad)
}
}
Section{}
Section {
Text("\(netWage, specifier: "%.2f")")
}
}
.navigationBarTitle("My Wage")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}`
I'm not sure I understand exactly what you're looking for, but it seems like you're saying you want to pick a date and find out what days are in period round that date. Here's some code:
import Foundation
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
if let date = dateFormatter.date(from: "October 21, 2021") {
let calendar = Calendar(identifier: .gregorian)
let datesInWeek = calendar.dateInterval(of: .weekOfYear, for: date)
if let datesInWeek = datesInWeek {
print("week from:")
print(dateFormatter.string(from: datesInWeek.start))
print("to:")
print(dateFormatter.string(from: datesInWeek.end))
}
}
The code takes the date "October 21, 2021" and uses dateInterval(of:for:) to calculate the days that are in the week surrounding that date. This will print out:
week from:
Oct 17, 2021
to:
Oct 24, 2021
NOTE: Your computer could come up with different dates depending on the Locale. I'm in the US and the US typically assumes Sunday to be the first day of the week. As I understand it, in Europe, Monday is usually the first day of the week. So If you get different dates with this same code, it might be because your locale is different.
maybe you can help me with following question:
I am programming a UI with two date pickers (startDatePicker and endDatePicker).
The startDatePicker should be updated itself to the date of endDatePicker in UI when the date of startEndPicker is smaller than the date of endDatePicker.
Do you habe any idea how I can realise that?
content.swift
import SwiftUI
struct ContentView: View {
#State var startDate = Date()
#State var endDate = Date()
#ObservedObject var dateModel = Period.shared
var body: some View {
VStack{
startDatePicker
endDatePicker
}
.onAppear {
// print("VStack")
// dateModel.startDate = startDate
// dateModel.endDate = endDate
}
}
var startDatePicker: some View{
DatePicker("Start", selection: $startDate, displayedComponents: [.date])
.datePickerStyle(CompactDatePickerStyle())
.frame(width: 250, height: 50, alignment: .center)
.onAppear(perform: {
print("StartDate.onAppear")
dateModel.startDate = dateModel.toLocalTime(date: startDate, type: true)
print(dateModel.startDate)
})
.onChange(of: startDate, perform: { startDate in
print("StartDate.onChange")
dateModel.startDate = dateModel.toLocalTime(date: startDate, type: true)
print(dateModel.startDate)
})
}
var endDatePicker: some View{
DatePicker("End", selection: $endDate, displayedComponents: [.date])
.datePickerStyle(CompactDatePickerStyle())
.frame(width: 250, height: 50, alignment: .center)
.onAppear(perform: {
print("EndDate.onAppear")
dateModel.endDate = dateModel.toLocalTime(date: endDate, type: false)
print(dateModel.endDate)
})
.onChange(of: endDate, perform: { endDate in
print("EndDate.onChange")
dateModel.endDate = dateModel.toLocalTime(date: endDate, type: false)
if dateModel.endDate < dateModel.startDate{
print("Error")
dateModel.startDate = dateModel.endDate
}
print(dateModel.endDate)
})
}
}
Datahandler.swift
class Period : ObservableObject{
static let shared = Period()
#Published var startDate: Date = Date()
#Published var endDate: Date = Date()
func toLocalTime(date : Date, type: Bool) -> Date {
var startDate : Date?
var endDate : Date?
var dateLocalTimezone : Date?
//Auswahl der aktuellen Kalender
let calendar = Calendar.current
//Auswahl der Zeitzone
let timezone = TimeZone.current
//Bestimmen Anzahl Sekunden zwischen Zeitzone und GMT
let seconds = TimeInterval(timezone.secondsFromGMT(for: date))
//Anpassen des eingelesenen Werts
if type == true {
startDate = calendar.date(bySettingHour: 00, minute: 00, second: 00, of: date)
dateLocalTimezone = Date(timeInterval: seconds, since: startDate!)
}else{
endDate = calendar.date(bySettingHour: 23, minute: 59, second: 00, of: date)
dateLocalTimezone = Date(timeInterval: seconds, since: endDate!)
}
return dateLocalTimezone!
}
}
Is there a better way for the code? The idea is to separate the part for dates from the UI.
You're almost there. You can move logic from onAppeat to init(), and from .onChange to didSet, like this:
struct ContentView: View {
#ObservedObject var dateModel = Period.shared
var body: some View {
VStack{
startDatePicker
endDatePicker
}
}
var startDatePicker: some View{
DatePicker("Start", selection: $dateModel.startDate, displayedComponents: [.date])
.datePickerStyle(CompactDatePickerStyle())
.frame(width: 250, height: 50, alignment: .center)
}
var endDatePicker: some View{
DatePicker("End", selection: $dateModel.endDate, displayedComponents: [.date])
.datePickerStyle(CompactDatePickerStyle())
.frame(width: 250, height: 50, alignment: .center)
}
}
class Period : ObservableObject{
static let shared = Period()
#Published var startDate: Date {
didSet {
let localTime = Self.toLocalTime(date: startDate, type: true)
if startDate != localTime {
startDate = localTime
}
}
}
#Published var endDate: Date {
didSet {
let localTime = Self.toLocalTime(date: endDate, type: false)
if endDate != localTime {
endDate = localTime
}
if endDate < startDate{
print("Error")
startDate = endDate
}
print(endDate)
}
}
init() {
startDate = Self.toLocalTime(date: Date(), type: true)
endDate = Self.toLocalTime(date: Date(), type: false)
}
static private func toLocalTime(date : Date, type: Bool) -> Date {
var startDate : Date?
var endDate : Date?
var dateLocalTimezone : Date?
//Auswahl der aktuellen Kalender
let calendar = Calendar.current
//Auswahl der Zeitzone
let timezone = TimeZone.current
//Bestimmen Anzahl Sekunden zwischen Zeitzone und GMT
let seconds = TimeInterval(timezone.secondsFromGMT(for: date))
//Anpassen des eingelesenen Werts
if type == true {
startDate = calendar.date(bySettingHour: 00, minute: 00, second: 00, of: date)
dateLocalTimezone = Date(timeInterval: seconds, since: startDate!)
}else{
endDate = calendar.date(bySettingHour: 23, minute: 59, second: 00, of: date)
dateLocalTimezone = Date(timeInterval: seconds, since: endDate!)
}
return dateLocalTimezone!
}
}
Your toLocalTime returns wrong value for end date, like I pass 2021-08-18 23:59:00 +0000 and the result is 2021-08-19 23:59:00 +0000 which is the next day. This proceeds to recursion of didSet, but I'll leave fixing this logic to your
It's not a good fit for SO to ask for "a better way", since every solution has its pros and cons and thus there are a lot of opinions. But the latter I guess, is pretty much consolidated (which is in itself highly opinionated ;) )
I would like to add some refactoring suggestions:
You can make the DatePickerView a reusable component:
struct DatePickerView: View {
let title: String
let date: Date
let setDateAction: (Date) -> Void
var body: some View {
let binding: Binding<Date> = .init {
return self.date
} set: { newValue in
self.setDateAction(newValue)
}
DatePicker(title, selection: binding, displayedComponents: [.date])
.datePickerStyle(CompactDatePickerStyle())
}
}
Then, it can be used in the ContentView as follows:
struct ContentView: View {
let state: TwoDatePickers.ViewModel.ViewState
let setStartDate: (Date) -> ()
let setEndDate: (Date) -> ()
var body: some View {
VStack{
Text("Start: \(state.startDate)")
.padding()
Text("End: \(state.endDate)")
.padding()
DatePickerView(
title: "Start",
date: state.startDate,
setDateAction: self.setStartDate)
.padding()
DatePickerView(
title: "End",
date: state.endDate,
setDateAction: self.setEndDate)
.padding()
}
}
}
You might notice that ContentView has no coupling to any certain kind of view model or model, and no logic what so ever. That's by intention to make it reusable as well and let the logic be done elsewhere.
Now, you can implement your view model plus logic as a separated component as well. I am cheating here a bit, since it internally uses a reusable "store" component ;)
extension TwoDatePickers {
static let store = Oak.Store(state: .init(),
update: update,
scheduler: DispatchQueue.main)
final class ViewModel: ObservableObject {
typealias ViewState = TwoDatePickers.State
init() {
cancellableState = store.sink { state in
self.viewState = self.view(state)
}
}
#Published
private(set) var viewState: ViewState = .init()
private var cancellableState: AnyCancellable!
private func view(_ state: State) -> ViewState { state }
func setStartDate(_ date: Date) {
store.input.send(.setStartDate(date))
}
func setEndDate(_ date: Date) {
store.input.send(.setEndDate(date))
}
}
}
Note, that the ViewModel is just a thin wrapper which connects the store and provides a view function which returns a ViewState from the store's state. The ViewState is the thing that completely and unambiguously defines what the view should render, while the store's State is there to perform the logic and may contain additional data. That is, ViewState is a function of State.
The "store" is implemented much like in Redux or Elm, which can be done in a few lines of code.
As mentioned, this is also a reusable component. It is event driven, unidirectional and uses internally a Finite State Machine to change state and generate outputs.
So, you have to implement an update function, which is basically the heart of your logic:
extension TwoDatePickers {
struct State {
var startDate: Date = Date()
var endDate: Date = Date()
}
enum Event {
case setStartDate(Date)
case setEndDate(Date)
}
typealias Command = Void
static func update(state: State, setter: (State) -> Void, event: Event) -> Void {
switch (state, event) {
case (_, .setStartDate(let date)):
let adjustedEndDate = Date(
timeIntervalSinceReferenceDate: max(
date.timeIntervalSinceReferenceDate,
state.endDate.timeIntervalSinceReferenceDate))
setter(State(startDate: date, endDate: adjustedEndDate))
case (_, .setEndDate(let date)):
let adjustedStartDate = Date(
timeIntervalSinceReferenceDate: min(
date.timeIntervalSinceReferenceDate,
state.startDate.timeIntervalSinceReferenceDate))
setter(State(startDate: adjustedStartDate, endDate: date))
default:
print("not handled: \(state), \(event)")
break
}
}
}
To wire all the things together, we may use a "root view". Here you can see how eventually the view model gets connected to the views:
struct TwoDatePickersSceneView: View {
#StateObject var viewModel = TwoDatePickers.ViewModel()
var body: some View {
TwoDatePickers.ContentView(
state: viewModel.viewState,
setStartDate: viewModel.setStartDate,
setEndDate: viewModel.setEndDate
)
}
}
What's left is the reusable implementation of the store. I post it here as a bonus:
https://gist.github.com/couchdeveloper/4100f1ec8470980c5c49adc119240de1
Final note:
This is an example how we can decompose a typical SwiftUI feature and separate it into several reusable components. You don't have to do this extra effort when the feature is small and tidy. However, this solution, especially using a Finite State Machine to solve UI problems scales much better for more complex problems.
So I'm trying to have a ForEach loop update the amount of times a View is looped based on what Month (value in a picker) is selected. In my case, they will be looping based on the number of days in the month of the selected month for the given year. I already have a function that gives me the number of days in each month, however, when I plug that into the ForEach Loop, it only gets run based on the first month selected and stays iterating the number of days of that month for the rest. Here is my code for the ForEach Loop:
ForEach(0..<getRange(year: yearIndex, month: monthIndex + indexCheck)) { i in
NavigationLink(destination: ContentView(day: yearData[yearIndex].months[monthIndex].dayInfo[i])) {
DayRow(day: yearData[yearIndex].months[monthIndex].dayInfo[i])
}
}
and here is the getRange() Function:
func getRange(year: Int, month: Int) -> Int {
return Calendar.current.range(of: .day, in: .month, for: Calendar.current.date(from: DateComponents(year: year + 2020, month: month + 1))!)!.count
}
The yearIndex variable is linked to the picker value of three years, (2020, 2021, 2022). Here is the code for it:
Picker("Years", selection: $yearIndex) {
ForEach(0 ..< year.count) { i in
Text(String(self.year[i])).tag(i)
}
}
.pickerStyle(SegmentedPickerStyle())
The monthIndex variable is linked to the picker with the months in the year (Jan-Dec). Here is the code for it:
Picker("Month", selection: $monthIndex) {
ForEach(0 ..< monthArray.count) { i in
Text(self.monthArray[i]).tag(i)
}
}
.padding(.bottom, 2)
I'm not sure what I'm doing wrong, and I'm not sure how to do this, so any help would be greatly appreciated! I'm still quite new to Swift/SwiftUI, so any advice to better code this would also be appreciated!
EDIT: Here is a minimal reproducible example as requested:
struct ContentView: View {
#State var year = [2020, 2021, 2022]
//monthSymbols gets an array of all the months
#State var monthArray = DateFormatter().monthSymbols!
#State var yearIndex = 0
#State var monthIndex = 0
#State var indexCheck = 0
#State var indexTest = 0
var body: some View {
NavigationView {
List {
Section {
VStack {
Picker("Years", selection: $yearIndex) {
ForEach(0 ..< year.count) { i in
Text(String(self.year[i])).tag(i)
}
}
.pickerStyle(SegmentedPickerStyle())
Divider()
Picker("Month", selection: $monthIndex) {
ForEach(0 ..< monthArray.count) { i in
Text(self.monthArray[i]).tag(i)
}
}
.padding(.bottom, 2)
}
}
Section(header: Text("What I love about you")) {
ForEach(0..<getRange(year: yearIndex, month: monthIndex + indexCheck)) { i in
NavigationLink(destination: DetailsView()) {
Text("Row \(i)")
}
}
}
}
.listStyle(InsetGroupedListStyle())
.navigationBarTitle(Text("\(monthArray[monthIndex + indexCheck]) \(String(year[yearIndex]))"))
}
}
func getRange(year: Int, month: Int) -> Int {
return Calendar.current.range(of: .day, in: .month, for: Calendar.current.date(from: DateComponents(year: year + 2020, month: month + 1))!)!.count
}
}
struct YearView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I cleaned a little bit your code so it's more readable.
Here is the ContentView:
struct ContentView: View {
let yearArray = [2020, 2021, 2022]
let monthArray = DateFormatter().monthSymbols!
// you don't need to operate on indices, you can use real values
#State var selectedYear = 2020
#State var selectedMonth = 1
// improved readability
var combinedYearMonth: String {
"\(monthArray[selectedMonth - 1]) \(selectedYear)"
}
var body: some View {
NavigationView {
List {
pickerSection
daySelectionSection
}
.listStyle(InsetGroupedListStyle())
.navigationBarTitle(combinedYearMonth)
}
}
}
The part responsible for displaying list sections:
// sections extracted to a private extension (you can still have everything in one `ContentView` struct if you want)
private extension ContentView {
var pickerSection: some View {
Section {
yearPicker
monthPicker
}
}
var daySelectionSection: some View {
Section(header: Text("What I love about you")) {
ForEach(dayRange, id: \.self) { day in
NavigationLink(destination: DetailsView()) {
Text("Day \(day)")
}
}
}
}
// create a range of days in the `selectedMonth` for the `selectedYear`
var dayRange: Range<Int> {
let dateComponents = DateComponents(year: selectedYear, month: selectedMonth)
let calendar = Calendar.current
let date = calendar.date(from: dateComponents)!
return calendar.range(of: .day, in: .month, for: date)!
}
}
And the part with pickers:
private extension ContentView {
var yearPicker: some View {
Picker("Years", selection: $selectedYear) {
ForEach(yearArray, id: \.self) { year in
Text(String(year)) // <- no need for `.tag()` if the `id` parameter in `ForEach` is specified
}
}
.pickerStyle(SegmentedPickerStyle())
}
var monthPicker: some View {
Picker("Month", selection: $selectedMonth) {
ForEach(1...12, id: \.self) { month in
Text(self.monthArray[month - 1])
}
}
.padding(.bottom, 2)
}
}