3

I'm exploring my way through swift & swiftui trying to teach myself. My current challenge is to produce a horizontal calendar that scrolls on a single line with a week dynamically adding days as necessary. Something like the image, any pointers on where to start with something like this? I figured a single view element for each day and some kind of loop through calender dates to build up the calender ...

looking to make something like this

I'm pretty much a beginner when it comes to dates / calendars. I managed the basics of formatting / converting and adding / subtracting days & months but that's pretty much where I'm at

I've rigged this for the current month HStack of days inside a scrollView but I can't figure out how to go about identifying which subview is visible in the centre of the scrollView - in part to be able to update the month name.

struct SingleCalendarView: View {
@State var monthString: String = "Not Set"

let calendar = Calendar.current

//var day:[Date]
var body: some View {
    let dates = getWeek()

    VStack {
        Text(getMonth(date: Date()))
        ScrollView(.horizontal) {
           HStack {
                ForEach(dates, id: \.self) { day in
                        VStack {
                            Text(getDayShort(date: day))
                                .font(.title3)
                            Text("\(getDayNumber(date: day))")
                                .font(.largeTitle)
                        }
                        .frame(width: 100, height: 100)
                    }
            }
        }
    }
}
func getMonth(date: Date) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "LLLL"
    return dateFormatter.string(from: date)
}

func getDayShort(date: Date) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "E"
    return dateFormatter.string(from: date)
}

func getDayNumber(date: Date) -> Int {
    let calendar = Calendar.current
    let components = calendar.dateComponents([.day], from: date)
    return components.day ?? 0
}

func getWeek() -> [Date] {
    let currentDate = Date()

    let calendar = Calendar.current
    let dayOfWeek = calendar.component(.weekday, from: currentDate)
    
    let range = calendar.range(of: .day, in: .month, for: currentDate)!
    
    let daysMonth = (range.lowerBound ..< range.upperBound)
        .compactMap { calendar.date(byAdding: .day, value: $0 - dayOfWeek, to: currentDate) }
    
    return daysMonth
}
}
  • 1
    Yes, an `HStack` with views representing each day sounds reasonable. Have you tried anything yet? Did you get stuck somewhere? SO works best with a concrete problem rather then a general "how should I start this" type question. – jnpdx Aug 22 '21 at 00:25

1 Answers1

1

I'm trying to do the same thing. I managed to implement the week view more or less in the same way as you, but currently I am stuck at trying to somehow swipe to a next/previous week. I build a method that retrieves the days for a specific week (based on current displayed week), but idk how to implement the swipe action to call that method. :) https://youtu.be/nKHrsrmA4lM this guys did an awesome job, but idk if we can use a SwipeView to swipe through weeks (swiping through weeks is not implemented in his video). Maybe a TabView with PageTabViewStyle but not sure how to dynamically request new week when swiping through the tab view.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 19 '22 at 14:46