A few things here:
You don't need to write this:
let months = [1,2,3,4,5,6,7,8,9,10,11,12]
You can use:
let months = [1...12]
But, you only use this once, so instead of this: ForEach (months, id: \.self) { month in you can use this: ForEach(1...12, id: \.self) { month in
Secondly, when you write
switch month {
case 01:
...
You've declared month as an Int, and you don't need to use leading zeroes, so you should write:
switch month {
case 1:
...
BUT... There's a much simpler way of doing this. Look into DateFormatter() with a format of MMM. Something like:
func getMonthText(_ month: Int) -> String {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US")
dateFormatter.dateFormat = "MM"
let firstOfMonth = dateFormatter.date(from: "\(month)")!
dateFormatter.dateFormat = "MMM"
return dateFormatter.string(from: firstOfMonth)
}
The issue you're having with presenting is because you've put the sheet inside the ForEach loop. You're only showing the sheet once when one thing is tapped, so you can just add it anywhere in the View. This works:
import SwiftUI
struct ContentView: View {
@State private var selectedMonth = 1
@State private var selectedYear = "2024"
@State private var isShowing = false
var body: some View {
List {
ForEach(1...12, id: \.self) { month in
HStack {
ViewList(month: month, year: selectedYear)
.onTapGesture {
isShowing = true
selectedMonth = month
}
}
}
}
.listRowSpacing(2)
.listStyle(.grouped)
// MOVED THIS TO HERE
.sheet(isPresented: $isShowing){
PopupView(month: selectedMonth, year: selectedYear)
.presentationDetents([.large])
}
}
}
struct ViewList: View {
var month: Int
var year: String
var body: some View {
VStack(alignment: .leading) {
Text("\(getMonthText(month)) / \(year)")
.font(.headline)
}
}
}
struct PopupView: View {
@Environment(\.dismiss) var dismiss
var month: Int
var year: String
@State private var selectedMonthText = "Jan"
@State private var imageText = "plus"
@State private var items = ["Cat", "Dog", "Bird", "Snake"]
var body: some View {
Button("Dismiss") {
dismiss()
}
Text("\(selectedMonthText) / \(year)")
List {
ForEach(items, id: \.self) {item in
HStack {
Text(item)
Text("Fed on: ")
Text(selectedMonthText)
}
}
}
.listRowSpacing(0)
.listStyle(.inset)
.onAppear {
selectedMonthText = getMonthText(month)
}
}
}
func getMonthText(_ month: Int) -> String {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US")
dateFormatter.dateFormat = "MM"
let firstOfMonth = dateFormatter.date(from: "\(month)")!
dateFormatter.dateFormat = "MMM"
return dateFormatter.string(from: firstOfMonth)
}
#Preview {
ContentView()
}