在日历视图中禁用所有其他日期

Disabling all other days in calendar view

我有一个表单,用户将在其中 select 天,然后 select 从日历视图中获取日期..

例如:用户将首先 select 星期日和星期一 .. 然后单击日期按钮,这样日历视图将显示 ..

我希望用户能够 select 星期天或星期一的日期..我想禁用其他日期并突出显示它们,例如..

最好的方法是什么?

我看到了这两个库:

https://cocoapods.org/pods/JTAppleCalendar

https://github.com/WenchaoD/FSCalendar

但没有找到任何可以帮助我完成我需要使用它们的东西..

最好的方法是什么?

您必须将星期日视为 1,将星期一视为 2,将星期二视为 3,以此类推,将星期六视为 7。

下面全局定义

fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian)
    fileprivate lazy var dateFormatter2: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()

    var arrDates = NSMutableArray()

viewDidLoad.

的下一行写
arrDates = self.getUserSelectedDates([1, 2], calender: self.calendarVW)

这里的1、2表示用户选择了星期一和星期二(所以这个数组只包含那些星期日和星期一的日期)

下面是 returns 日期数组的函数,日期数组基于日期值,如 1,2 等等,直到 7。

func getUserSelectedDates(_ arrWeekDay: [Int], calender calenderVW: FSCalendar?) -> NSMutableArray {
        let arrUnAvailibilityDates = NSMutableArray()
        let currentDate: Date? = calenderVW?.currentPage
        //get calender
        let gregorianCalendar = Calendar.init(identifier: .gregorian)
        // Start out by getting just the year, month and day components of the current date.
        var components: DateComponents? = nil
        if let aDate = currentDate {
            components = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aDate)
        }
        // Change the Day component to 1 (for the first day of the month), and zero out the time components.
        components?.day = 1
        components?.hour = 0
        components?.minute = 0
        components?.second = 0
        //get first day of current month
        var firstDateOfCurMonth: Date? = nil
        if let aComponents = components {
            firstDateOfCurMonth = gregorianCalendar.date(from: aComponents)
        }
        //create new component to get weekday of first date
        var newcomponents: DateComponents? = nil
        if let aMonth = firstDateOfCurMonth {
            newcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
        }
        let firstDateWeekDay: Int? = newcomponents?.weekday
        //get last month date
        let curMonth: Int? = newcomponents?.month
        newcomponents?.month = (curMonth ?? 0) + 1
        var templastDateOfCurMonth: Date? = nil
        if let aNewcomponents = newcomponents {
            templastDateOfCurMonth = gregorianCalendar.date(from: aNewcomponents)?.addingTimeInterval(-1)
        }
        // One second before the start of next month
        var lastcomponents: DateComponents? = nil
        if let aMonth = templastDateOfCurMonth {
            lastcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
        }
        lastcomponents?.hour = 0
        lastcomponents?.minute = 0
        lastcomponents?.second = 0
        var lastDateOfCurMonth: Date? = nil
        if let aLastcomponents = lastcomponents {
            lastDateOfCurMonth = gregorianCalendar.date(from: aLastcomponents)
        }
        var dayDifference = DateComponents()
        dayDifference.calendar = gregorianCalendar

        if arrWeekDay.count == 0 {

        } else if arrWeekDay.count == 1 {
            let wantedWeekDay = Int(arrWeekDay[0])
            var firstWeekDateOfCurMonth: Date? = nil
            if wantedWeekDay == firstDateWeekDay {
                firstWeekDateOfCurMonth = firstDateOfCurMonth
            } else {
                var day: Int = wantedWeekDay - firstDateWeekDay!
                if day < 0 {
                    day += 7
                }
                day += 1
                components?.day = day
                firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
            }
            var weekOffset: Int = 0
            var nextDate: Date? = firstWeekDateOfCurMonth
            repeat {
                let strDT: String = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))!
                arrUnAvailibilityDates.add(strDT)
                weekOffset += 1
                dayDifference.weekOfYear = weekOffset
                var date: Date? = nil
                if let aMonth = firstWeekDateOfCurMonth {
                    date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
                }
                nextDate = date
            } while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
        }
        else {
            for i in 0..<arrWeekDay.count {
                let wantedWeekDay = Int(arrWeekDay[i])
                var firstWeekDateOfCurMonth: Date? = nil
                if wantedWeekDay == firstDateWeekDay {
                    firstWeekDateOfCurMonth = firstDateOfCurMonth
                } else {
                    var day: Int = wantedWeekDay - firstDateWeekDay!
                    if day < 0 {
                        day += 7
                    }
                    day += 1
                    components?.day = day
                    firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
                }


                var weekOffset: Int = 0
                var nextDate: Date? = firstWeekDateOfCurMonth
                repeat {
                    let strDT = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))
                    arrUnAvailibilityDates.add(strDT!)
                    weekOffset += 1
                    dayDifference.weekOfYear = weekOffset
                    var date: Date? = nil
                    if let aMonth = firstWeekDateOfCurMonth {
                        date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
                    }
                    nextDate = date
                } while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
            }
        }
        return arrUnAvailibilityDates
    }


func getSmallFormatedDate(_ localDate: Date?) -> String? {
        let dateFormatter = DateFormatter()
        let timeZone = NSTimeZone(name: "UTC")
        if let aZone = timeZone {
            dateFormatter.timeZone = aZone as TimeZone
        }
        dateFormatter.dateFormat = "yyyy-MM-dd"
        var dateString: String? = nil
        if let aDate = localDate {
            dateString = dateFormatter.string(from: aDate)
        }
        return dateString
    }

    func convertCalendarDate(toNormalDate selectedDate: Date?) -> Date? {
        let sourceTimeZone = NSTimeZone(abbreviation: "UTC")
        let destinationTimeZone = NSTimeZone.system as NSTimeZone
        var sourceGMTOffset: Int? = nil
        if let aDate = selectedDate {
            sourceGMTOffset = sourceTimeZone?.secondsFromGMT(for: aDate)
        }
        var destinationGMTOffset: Int? = nil
        if let aDate = selectedDate {
            destinationGMTOffset = destinationTimeZone.secondsFromGMT(for: aDate)
        }
        let interval1 = TimeInterval((destinationGMTOffset ?? 0) - (sourceGMTOffset ?? 0))
        var localDate: Date? = nil
        if let aDate = selectedDate {
            localDate = Date(timeInterval: interval1, since: aDate)
        }
        return localDate
    }

下面是 FSCalendar 代表

extension ViewController: FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance {
    func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
        self.view.layoutIfNeeded()
    }

    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
    }

    func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
        arrDates = self.getUserSelectedDates([3, 4], calender: self.calendarVW)
    }

    func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor? {
        if arrDates.contains(dateFormatter2.string(from: date)) {
            return UIColor.green
        } else {
            return UIColor.red
        }
    }

    func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
        if arrDates.contains(dateFormatter2.string(from: date)) {
            return true
        }
        else {
            return false
        }
    }

}

对于 JTApplecalendar 这很容易

func calendar(_ calendar: JTAppleCalendarView, shouldSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) -> Bool {
    return cellState.day == .monday || cellState.day == .sunday
}

完成。

对于功能日历检查星期六或星期日然后它没有 select。 Swift 4.2的解决方案:

 func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
   return CheckSatSunday(today: date)
}

// Check Today Is Saturday or Sunday

func CheckSatSunday(today:Date) ->Bool{

 var DayExist:Bool
   // let today = NSDate()

    let calendar = 
     NSCalendar(calendarIdentifier:NSCalendar.Identifier.gregorian)
    let components = calendar!.components([.weekday], from: today)

    if components.weekday == 1 {
        print("Hello Sunday")
        self.showToast(message: "Sunday is Off")
        DayExist = false
    } else if components.weekday == 7{
        print("Hello Saturday")
        self.showToast(message: "Saturday is Off")
         DayExist = false
    } else{
        print("It's not Saturday and  Sunday ")
        DayExist = true
    }
    print("weekday :\(String(describing: components.weekday)) ")
    return DayExist
}