Swift 4中如何在CollectionView同时显示公历与农历日历?
解决iOS Swift应用中显示农历日期的问题
嘿,很高兴能帮你搞定这个农历显示的需求!其实实现起来并不复杂,主要有两种靠谱的方案:用系统自带的Calendar框架(不需要依赖第三方),或者用成熟的第三方库快速搞定。下面我给你详细拆解一下:
方案一:用系统原生Calendar实现(推荐,无依赖)
iOS的Calendar类已经内置了对农历(Chinese Calendar)的支持,我们只需要创建对应的日历实例,就能把公历日期转换成农历信息。
步骤1:创建农历日历实例
首先初始化一个农历专属的Calendar对象:
let chineseLunarCalendar = Calendar(identifier: .chinese)
步骤2:获取公历日期对应的农历组件
从你已经能显示的公历Date对象中,提取农历的年、月、日组件:
// 假设你已经有了要显示的公历日期(比如当前日期或者日历选中的日期) let targetGregorianDate = Date() // 提取农历的年、月、日组件 let lunarDateComponents = chineseLunarCalendar.dateComponents([.year, .month, .day], from: targetGregorianDate)
步骤3:格式化农历为中文显示
系统的Calendar已经提供了农历月份和日期的中文名称数组,我们可以直接拿来用:
// 获取农历月份的中文名称(比如["正月", "二月", ..., "闰十二月"]) let lunarMonthNames = chineseLunarCalendar.monthSymbols // 获取农历日期的中文名称(比如["初一", "初二", ..., "三十"]) let lunarDayNames = chineseLunarCalendar.daySymbols // 组装完整的农历日期字符串 if let lunarYear = lunarDateComponents.year, let lunarMonth = lunarDateComponents.month, let lunarDay = lunarDateComponents.day { // 处理天干地支年份(比如"甲辰年") func getChineseYearName(from year: Int) -> String { let heavenlyStems = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"] let earthlyBranches = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"] let stemIndex = (year - 4) % 10 let branchIndex = (year - 4) % 12 return "\(heavenlyStems[stemIndex])\(earthlyBranches[branchIndex])年" } let lunarYearString = getChineseYearName(from: lunarYear) let lunarMonthString = lunarMonthNames[lunarMonth - 1] let lunarDayString = lunarDayNames[lunarDay - 1] // 最终农历字符串,比如"甲辰年五月廿三" let fullLunarDateString = "\(lunarYearString)\(lunarMonthString)\(lunarDayString)" // 把这个字符串赋值给你的农历Label即可 // lunarDateLabel.text = fullLunarDateString }
额外处理:闰月的情况
系统的Calendar会自动识别闰月,monthSymbols数组里已经包含了"闰正月"、"闰二月"这类名称,所以上面的代码不需要额外处理,直接用就行。如果需要单独判断是否是闰月,可以用:
let isLeapMonth = chineseLunarCalendar.isDateInLeapMonth(for: targetGregorianDate)
方案二:用第三方库快速实现
如果不想自己写天干地支的逻辑,或者需要更丰富的农历功能(比如节气、生肖),可以用成熟的第三方库,比如LunarSwift或者ChineseLunarCalendar。这里以LunarSwift为例:
步骤1:集成库
用Swift Package Manager集成的话,在Xcode中添加依赖即可。
步骤2:代码示例
集成后只需要几行代码就能得到完整的农历信息:
import LunarSwift let targetGregorianDate = Date() let lunarDate = Lunar(date: targetGregorianDate) // 获取完整农历字符串,比如"甲辰年五月廿三" let fullLunarString = lunarDate.chineseDateString // 获取生肖 let zodiac = lunarDate.zodiac // 获取节气(如果有的话) let solarTerm = lunarDate.solarTerm // 赋值给UI控件即可 // lunarDateLabel.text = fullLunarString
最后一步:UI展示
把你已经实现的公历日期显示在上方Label,把上面得到的农历字符串显示在下方Label,就能实现你想要的双日历效果啦!
内容的提问来源于stack exchange,提问作者Thành Trung Nguyễn




