SwiftUI:如何根据日期每天显示一个新视图,而以前的视图持续一周
Posted
技术标签:
【中文标题】SwiftUI:如何根据日期每天显示一个新视图,而以前的视图持续一周【英文标题】:SwiftUI: How to have a a new view show every day based on the date with previous views lasting a week 【发布时间】:2020-07-10 21:57:22 【问题描述】:老实说,我被困住了。我正在尝试制作类似于 App Store 的东西,其中有一个“今天”视图,其中包含当前日期的内容。在此之下,我希望显示最后 6 天。我已经想出了如何让过去一周每天都出现一个新视图,只要过去一周是在同一个月内。一旦新的一个月到来,我不知道如何使它工作,因为我这样做的方式是使用当前日期,减去 6 天,然后在这两天之间获得一个范围。一旦新的月份到来,它就会中断,因为范围从看起来像 12...18 变为 30...5,这打破了它!话虽如此,它比这更复杂一些。我试图迭代的视图有 3 个输入——一年、一个月和一天。这一天是我一直在使用范围进行迭代的一天。这是我的代码:
// 主视图 //
struct HomeView: View
let future = Calendar.current.date(byAdding: DateComponents(day: 25), to: Date())!
let aWeekAgo = Calendar.current.date(byAdding: DateComponents(day: -6), to: Calendar.current.date(byAdding: DateComponents(day: 28), to: Date())!)!
var body: some View
ScrollView
VStack(spacing: 40)
ForEach((dayRange).reversed(), id: \.self) i in
CardView(day: yearData[0].months[0].dayInfo[i])
.padding(.bottom, 40)
// HomeView 扩展 //
extension HomeView
var dayRange: Range<Int>
let day = Calendar.current.dateComponents([.day, .month, .year], from: future)
let dayAWeekago = Calendar.current.dateComponents([.day, .month, .year], from: aWeekAgo)
return ((dayAWeekago.day! - 1)..<day.day!)
var monthRange: ClosedRange<Int>
let month = Calendar.current.dateComponents([.month], from: future)
let monthAWeekAgo = Calendar.current.dateComponents([.month], from: aWeekAgo)
return ((monthAWeekAgo.month! - 7)...(month.month! - 7))
// CardView //
struct CardView: View
var day: YearModel.MonthModel.DayModel
@Environment(\.colorScheme) var colorScheme
var body: some View
Image(day.imageName)
.resizable()
.scaledToFill()
.frame(width: UIScreen.main.bounds.width - 40, height: UIScreen.main.bounds.height * 0.6, alignment: .top)
.border(Color(.sRGB, red: 150/255, green: 150/255, blue: 150/255, opacity: 0.1), width: 1)
.overlay(
VStack
Spacer()
Rectangle()
.frame(minHeight: 50, maxHeight: 100)
.overlay(
HStack
VStack(alignment: .leading)
Text("\(day.date) - DAY \(day.id)")
.font(.subheadline)
.fontWeight(.bold)
.foregroundColor(.secondary)
Text(day.whatILove)
.font(.title)
.fontWeight(.bold)
.foregroundColor(.primary)
.fixedSize(horizontal: false, vertical: true)
.padding()
Spacer()
)
.foregroundColor(.white)
)
.cornerRadius(15)
.shadow(color: Color.black.opacity(colorScheme == .dark ? 0 : 0.3), radius: 15, y: 20)
// YearModel.swift //
struct YearModel: Codable
let year: Int
let months: [MonthModel]
struct MonthModel: Codable
let monthName: String
let dayInfo: [DayModel]
struct DayModel: Codable
let whatILove: String
let imageName: String
let date: String
let paragraph: String
let id: Int
// JSON 解码文件 //
let yearData: [YearModel] = load("Data.json")
func load<T: Decodable>(_ filename: String) -> T
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else
fatalError("Couldn't find \(filename) in main bundle.")
do
data = try Data(contentsOf: file)
catch
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
do
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
catch
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
// 最后,我正在为信息解码的 JSON 文件 //
[
"year": 2020,
"months": [
"monthName": "July",
"dayInfo": [
"whatILove": "I Love You",
"imageName": "image1",
"date": "07/22/2020",
"paragraph": "...",
"id": 1
,
"whatILove": " I Love Your Laugh",
"imageName": "image2",
"date": "07/23/2020",
"paragraph": "...",
"id": 2
,
"whatILove": "I Love Your Smile",
"imageName": "image3",
"date": "07/24/2020",
"paragraph": "...",
"id": 3
,
"whatILove": "I Love Your Kindness",
"imageName": "image4",
"date": "07/25/2020",
"paragraph": "...",
"id": 4
,
"whatILove": " I Love Your Nose",
"imageName": "image5",
"date": "07/26/2020",
"paragraph": "...",
"id": 5
,
"whatILove": "I Love Who You Are",
"imageName": "image6",
"date": "07/27/2020",
"paragraph": "...",
"id": 6
,
"whatILove": "I Love Your Freckles",
"imageName": "image7",
"date": "07/28/2020",
"paragraph": "...",
"id": 7
,
"whatILove": "I Love That You Are Trustworthy",
"imageName": "image8",
"date": "07/29/2020",
"paragraph": "...",
"id": 8
,
"whatILove": " I Love Your Ears",
"imageName": "image9",
"date": "07/30/2020",
"paragraph": "...",
"id": 9
,
"whatILove": "Happy 2 Years!",
"imageName": "image10",
"date": "07/31/2020",
"paragraph": "...",
"id": 10
]
,
"monthName": "August",
"dayInfo": [
"whatILove": "I Love Your Music",
"imageName": "image11",
"date": "08/01/2020",
"paragraph": "...",
"id": 11
,
"whatILove": "I Love That You Are Trustworthy",
"imageName": "image12",
"date": "08/02/2020",
"paragraph": "...",
"id": 12
,
"whatILove": "I Love Your Kisses",
"imageName": "image13",
"date": "08/03/2020",
"paragraph": "...",
"id": 13
,
"whatILove": "I Love Your...",
"imageName": "image14",
"date": "08/04/2020",
"paragraph": "...",
"id": 14
,
"whatILove": "I Love Your...",
"imageName": "image15",
"date": "08/05/2020",
"paragraph": "",
"id": 15
,
"whatILove": "I Love Your...",
"imageName": "image16",
"date": "08/06/2020",
"paragraph": "...",
"id": 16
,
"whatILove": "I Love Your...",
"imageName": "image17",
"date": "08/07/2020",
"paragraph": "...",
"id": 17
,
"whatILove": "I Love Your...",
"imageName": "image18",
"date": "08/08/2020",
"paragraph": "...",
"id": 18
,
"whatILove": "I Love Your...",
"imageName": "image19",
"date": "08/09/2020",
"paragraph": "...",
"id": 19
,
"whatILove": "I Love Your...",
"imageName": "image20",
"date": "08/10/2020",
"paragraph": "...",
"id": 20
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/11/2020",
"paragraph": "...",
"id": 21
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/12/2020",
"paragraph": "...",
"id": 22
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/13/2020",
"paragraph": "...",
"id": 23
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/14/2020",
"paragraph": "...",
"id": 24
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/15/2020",
"paragraph": "...",
"id": 25
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/16/2020",
"paragraph": "...",
"id": 26
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/17/2020",
"paragraph": "...",
"id": 27
,
"whatILove": "I Love Your...",
"imageName": "image6",
"date": "08/18/2020",
"paragraph": "...",
"id": 28
,
"whatILove": "I Love Your...",
"imageName": "image4",
"date": "08/19/2020",
"paragraph": "...",
"id": 29
,
"whatILove": "I Love Your...",
"imageName": "image2",
"date": "08/20/2020",
"paragraph": "...",
"id": 30
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/21/2020",
"paragraph": "...",
"id": 31
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/22/2020",
"paragraph": "...",
"id": 32
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/23/2020",
"paragraph": "...",
"id": 33
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/24/2020",
"paragraph": "...",
"id": 34
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/25/2020",
"paragraph": "...",
"id": 35
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/26/2020",
"paragraph": "...",
"id": 36
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/27/2020",
"paragraph": "...",
"id": 37
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/28/2020",
"paragraph": "...",
"id": 38
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/29/2020",
"paragraph": "...",
"id": 39
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/31/2020",
"paragraph": "...",
"id": 41
]
,
"monthName": "September",
"dayInfo": [
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 42
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 40
,
"whatILove": "I Love Your...",
"imageName": "image3",
"date": "08/30/2020",
"paragraph": "...",
"id": 71
,
]
]
,
"year": 2021,
"months": [
"monthName": "January",
"dayInfo": [
"whatILove": "I Love Your Smile",
"imageName": "image1",
"date": "01/01/2021",
"paragraph": "...",
"id": 1
,
"whatILove": "I Love Your Laugh",
"imageName": "image2",
"date": "01/02/2021",
"paragraph": "...",
"id": 2
]
,
"monthName": "February",
"dayInfo": [
"whatILove": "I Love Your Music",
"imageName": "image4",
"date": "08/01/2020",
"paragraph": "...",
"id": 11
,
"whatILove": "I Love Your Kiss",
"imageName": "image6",
"date": "08/02/2020",
"paragraph": "...",
"id": 12
]
]
]
我知道代码很多,但我希望这不会吓跑人们!无论如何,非常感谢任何帮助!
【问题讨论】:
【参考方案1】:编辑 2:
使用一个 DateComponents 数组来描述过去六天,包括它们的月份和年份。这样,您可以让 DateComponents 处理处理使用两个月甚至两年的范围的工作。
/// Calculates Dates for the last n days, starting with the previous day.
func lastNDays(n: Int) -> [Date]?
guard n > 0 else return nil
var result = [Date]()
for i in 1...n
guard let ithPreviousDay = Calendar.current.date(byAdding: DateComponents(day: -i), to: Date()) else
return nil
result.append(ithPreviousDay)
return result
var lastSixDaysAsDateComponents: [DateComponents]
guard let lastSixDays = lastNDays(n: 6) else return []
return lastSixDays.map day in
Calendar.current.dateComponents([.day, .month, .year], from: day)
然后在你的视图正文中:
ForEach(self.lastSixDaysAsDateComponents, id: \.self) dateComp in
CardViewday: yearData[dateComp.year!].months[dateComp.month!].dayInfo[dateComp.day!])
【讨论】:
非常感谢您的回复!所以我尝试实现这个,似乎我得到了这个错误:在'Range'上引用实例方法'reversed()'要求'DayInMonth'符合'Strideable'。我尝试删除 .reversed() 以查看是否可以修复它,尽管它仍然给了我同样的错误!知道如何解决这个问题吗? 我已经编辑了我的答案,现在它实际上更接近你原来的方法。我想知道为什么你总是访问几个月[0]。这是故意的吗? 不,这不是故意的!这是我一直试图弄清楚如何添加到其中的输入之一,与当年相同!使用类似于你在那里所做的,我做了几个月,返回了几个月的数组,但我意识到我没有办法使用我知道的它,因为我需要以某种方式使用日内月!我把它放在代码中的原因是因为否则它不会正确运行,尽管我意识到我应该更具体地提到这些输入!关于如何做到这一点的任何想法? 在这种情况下,我将构建一个包含 6 个 DateComponents 的数组,其中每个代表过去 6 天中的一个。将该数组传递给您的视图,在 ForEach 中,您可以访问每个 DateComponents 结构的日期、月份和年份。使用该信息,您可以使用三个值访问您的模型。也许效果更好? 你知道我会怎么做吗?以上是关于SwiftUI:如何根据日期每天显示一个新视图,而以前的视图持续一周的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:如何使用语义放置呈现多个 ToolbarItem?