You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FSCalendar(Swift 4)技术问题:指定周起始日期及周视图以今日为起点

FSCalendar: Customizing Week Start and Locking Week View to Today's Week

Hey there! Let's break down your two FSCalendar requirements with practical, code-based solutions — I’ve tinkered with this library a lot, so I know the ins and outs here.


1. Set a Custom Week Start Day

FSCalendar has a built-in property to control which day kicks off the week, and this affects both month and week views directly. Here's how to implement it:

Swift Implementation

Drop this into your viewDidLoad (or wherever you configure your calendar instance):

// Initialize and add the calendar to your view
let calendar = FSCalendar(frame: CGRect(x: 0, y: 100, width: view.frame.width, height: 300))
view.addSubview(calendar)

// Set the first weekday: 1 = Sunday, 2 = Monday, 3 = Tuesday, ..., 7 = Saturday
calendar.firstWeekday = 2 // Example: Make Monday the week start

Objective-C Implementation

FSCalendar *calendar = [[FSCalendar alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 300)];
[self.view addSubview:calendar];

// Set Monday as the week start
calendar.firstWeekday = 2;

This overrides the default system locale's week start, so your calendar will consistently use the day you specify.


2. Lock Week View to Today's Full Week

To make the week view always show today's full 7-day week and stay anchored there, we'll calculate the current week's date range and configure the calendar to stick to it.

Step 1: Calculate Today's Week Range

First, write a helper method to get the start and end dates of the current week (match your custom week start if you set one):

Swift

func getCurrentWeekRange() -> (start: Date, end: Date) {
    // Use a calendar instance that matches your FSCalendar's week start
    var calendar = Calendar(identifier: .gregorian)
    calendar.firstWeekday = self.calendar.firstWeekday // Sync with your calendar's setting

    // Get the start of the current week
    guard let startOfWeek = calendar.date(from: calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date())) else {
        fatalError("Failed to calculate start of week")
    }
    // Add 6 days to get the end of the week
    let endOfWeek = calendar.date(byAdding: .day, value: 6, to: startOfWeek)!
    
    return (startOfWeek, endOfWeek)
}

Objective-C

- (NSDate *)startOfCurrentWeek {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    calendar.firstWeekday = self.calendar.firstWeekday; // Match your FSCalendar's week start
    
    NSDateComponents *weekComponents = [calendar components:NSCalendarUnitYearForWeekOfYear | NSCalendarUnitWeekOfYear fromDate:[NSDate date]];
    return [calendar dateFromComponents:weekComponents];
}

- (NSDate *)endOfCurrentWeek {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    return [calendar dateByAddingUnit:NSCalendarUnitDay value:6 toDate:[self startOfCurrentWeek] options:0];
}

Step 2: Configure the Week View

Now set up the calendar to display only today's week, with optional locks to prevent scrolling away:

Swift

// Switch to week view mode
calendar.scope = .week

let weekRange = getCurrentWeekRange()
// Jump directly to the start of today's week
calendar.setCurrentPage(weekRange.start, animated: false)

// Optional: Block users from scrolling outside today's week
calendar.minimumDate = weekRange.start
calendar.maximumDate = weekRange.end

// Optional: Auto-revert to today's week if user tries to scroll away
func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
    let weekRange = getCurrentWeekRange()
    let currentPage = calendar.currentPage
    
    // Check if the current page is outside the week bounds
    if !calendar.date(weekRange.start, isEqualOrAfter: currentPage) || !calendar.date(weekRange.end, isEqualOrBefore: currentPage) {
        calendar.setCurrentPage(weekRange.start, animated: true)
    }
}

Objective-C

// Switch to week view
self.calendar.scope = FSCalendarScopeWeek;

NSDate *startOfWeek = [self startOfCurrentWeek];
NSDate *endOfWeek = [self endOfCurrentWeek];

// Scroll to today's week
[self.calendar setCurrentPage:startOfWeek animated:NO];

// Optional: Lock to this week
self.calendar.minimumDate = startOfWeek;
self.calendar.maximumDate = endOfWeek;

// Optional: Auto-revert to today's week on scroll
- (void)calendarCurrentPageDidChange:(FSCalendar *)calendar {
    NSDate *startOfWeek = [self startOfCurrentWeek];
    NSDate *endOfWeek = [self endOfCurrentWeek];
    NSDate *currentPage = calendar.currentPage;
    
    if (![calendar date:startOfWeek isEqualOrAfter:currentPage] || ![calendar date:endOfWeek isEqualOrBefore:currentPage]) {
        [calendar setCurrentPage:startOfWeek animated:YES];
    }
}

Hope these solutions fit your needs perfectly! If you hit any edge cases (like handling locale changes or leap years), feel free to tweak the helper methods to match your app's specific behavior.

内容的提问来源于stack exchange,提问作者kakubei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:19:23