显示输入日期并改变方向
Display Entry Date with Change in Orientation
我正在努力获得一个函数来显示日期,仅当它是列表中的第一个日期或与上一个条目日期不同的条目时。除非更改 phone 方向,否则代码似乎可以正常工作。我有一个变量 (listDate) 保存上一个条目日期,它在放入此模块之前被初始化为“”。改变方向是不同的。我已经尝试使用 .onAppear 和 .onChange 的方向数据,但没有任何运气让模块在方向改变时显示列表中带有日期的第一个条目。
感兴趣的函数 (ckDateStatus) 位于此清单的底部。
谢谢你的帮助。
struct WithdrawalView: View {
@EnvironmentObject var bank: BankWithdrawal
var body: some View {
GeometryReader { g in
VStack (alignment: .leading) {
List {
WDTitleView(g: g)
ForEach(bank.wdItem, id: \.id) { item in
showSingleWdRow(g: g, item: item )
}.onDelete(perform: deleteItem)
}
}
}
}
}
struct showSingleWdRow: View {
@EnvironmentObject var bank: BankWithdrawal
@EnvironmentObject var orientInfo: DeviceOrientation
var g: GeometryProxy
var item: WdItem
var body: some View {
let entryDate = self.ckDateStatus( cDate: item.wdDate)
// if withdrawal date is the same as the previous entry skip date and proceed to time
if !entryDate.isEmpty {
Text(entryDate)
}
// show time, local and home currency amount
ShowRowTopLine(g:g, item: item)
.font(.subheadline)
// show withdrawal location
if g.size.width > g.size.height {
Text("\(item.wdCity), \(item.wdState), \(item.wdCountry)")
//}
// .onChange(of: orientInfo.orientation == .portrait) { newValue in
// bank.listDate = ""
// }
// if orientInfo.orientation == .portrait {
// Text("portrait")
// } else {
// Text("landscape")
// }
}
}
// check if the entry date is the 1st entry in list or the same as previous date
func ckDateStatus( cDate: Date) -> (String) {
var outDate: String = ""
// initialzie the entry date
let entryDate = cDate.formatted(.dateTime.year().day().month(.wide))
// if saved date is blank -> no previous entries
if bank.listDate.isEmpty {
outDate = entryDate
}
else { // saved date is not blank
if bank.listDate == entryDate {
outDate = ""
}
else { // date entries different
outDate = entryDate
}
}
bank.listDate = entryDate
// outDate returns blank or the current date
return (outDate)
}
}
您的方法存在的问题是 SwiftUI 仅重绘必须重绘的单元格。所以在方向改变时,不能保证所有的单元格都会被刷新。
你可以通过添加到你的外部来解决这个问题!查看:
.id(orientInfo)
这将在 orientInfo
更改时强制重绘视图。
但我会根据 pre-organizing 你的数据建议另一种方法。
您可以创建一个包含您拥有的所有唯一日期的数组,然后按该日期过滤条目。然后可以使用这些数组以您想要的方式显示您的数据——它也可以安全地处理方向变化。
struct ContentView: View {
// dummy data
let bank: [BankWithdrawal] = [
BankWithdrawal(wdDate: "22/03/01", wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: "22/03/01", wdAmount: 100, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/02", wdAmount: 300, wdCity: "Orlando", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/02", wdAmount: 150, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: "22/03/02", wdAmount: 200, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/03", wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: "22/03/04", wdAmount: 500, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: "22/03/04", wdAmount: 150, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/04", wdAmount: 250, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: "22/03/05", wdAmount: 150, wdCity: "S.F.", wdState: "CA")
]
// creates a list of unique date entries
// (goes through all elements, saves them in a set, checks if already in set)
var uniqueBankDates: [BankWithdrawal] {
var seen: Set<String> = []
return bank.filter { seen.insert([=11=].wdDate).inserted }
}
// filters entries for the given date
func bankEntries(for date: String) -> [BankWithdrawal] {
return bank.filter { [=11=].wdDate == date }
}
var body: some View {
List {
// outer ForEach with unique dates
ForEach(uniqueBankDates) { dateItem in
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem.wdDate)) { item in
Text("$\(item.wdAmount, specifier: "%.2f") \(item.wdCity), \(item.wdState)")
}
} header: {
Text(dateItem.wdDate)
}
}
}
}
}
struct BankWithdrawal: Identifiable {
let id = UUID()
var wdDate: String
var wdAmount: Double
var wdCity: String
var wdState: String
var wdCountry: String = "USA"
}
编辑:
使用 Date()
时,您可以这样做:
struct ContentView: View {
// dummy data
let bank: [BankWithdrawal] = [
BankWithdrawal(wdDate: Date(), wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: Date(), wdAmount: 100, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: Date(), wdAmount: 300, wdCity: "Orlando", wdState: "FL"),
BankWithdrawal(wdDate: Date(), wdAmount: 150, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: Date(), wdAmount: 200, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: Date(), wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 500, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 150, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 250, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 150, wdCity: "S.F.", wdState: "CA")
]
// creates a list of unique date entries
// (goes through all elements, saves them in a set, checks if already in set)
var uniqueBankDates: [String] {
var seen: Set<String> = []
return bank.filter { seen.insert([=12=].wdDate.formatted(date: .abbreviated, time: .omitted)).inserted }
.map {[=12=].wdDate.formatted(date: .abbreviated, time: .omitted) }
}
// filters entries for the given date
func bankEntries(for date: String) -> [BankWithdrawal] {
return bank.filter { [=12=].wdDate.formatted(date: .abbreviated, time: .omitted) == date }
}
var body: some View {
List {
// outer ForEach with unique dates
ForEach(uniqueBankDates, id: \.self) { dateItem in
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem)) { item in
Text("$\(item.wdAmount, specifier: "%.2f") \(item.wdCity), \(item.wdState)")
}
} header: {
Text("\(dateItem)")
}
}
}
}
}
struct BankWithdrawal: Identifiable {
let id = UUID()
var wdDate: Date
var wdAmount: Double
var wdCity: String
var wdState: String
var wdCountry: String = "USA"
}
我正在努力获得一个函数来显示日期,仅当它是列表中的第一个日期或与上一个条目日期不同的条目时。除非更改 phone 方向,否则代码似乎可以正常工作。我有一个变量 (listDate) 保存上一个条目日期,它在放入此模块之前被初始化为“”。改变方向是不同的。我已经尝试使用 .onAppear 和 .onChange 的方向数据,但没有任何运气让模块在方向改变时显示列表中带有日期的第一个条目。
感兴趣的函数 (ckDateStatus) 位于此清单的底部。
谢谢你的帮助。
struct WithdrawalView: View {
@EnvironmentObject var bank: BankWithdrawal
var body: some View {
GeometryReader { g in
VStack (alignment: .leading) {
List {
WDTitleView(g: g)
ForEach(bank.wdItem, id: \.id) { item in
showSingleWdRow(g: g, item: item )
}.onDelete(perform: deleteItem)
}
}
}
}
}
struct showSingleWdRow: View {
@EnvironmentObject var bank: BankWithdrawal
@EnvironmentObject var orientInfo: DeviceOrientation
var g: GeometryProxy
var item: WdItem
var body: some View {
let entryDate = self.ckDateStatus( cDate: item.wdDate)
// if withdrawal date is the same as the previous entry skip date and proceed to time
if !entryDate.isEmpty {
Text(entryDate)
}
// show time, local and home currency amount
ShowRowTopLine(g:g, item: item)
.font(.subheadline)
// show withdrawal location
if g.size.width > g.size.height {
Text("\(item.wdCity), \(item.wdState), \(item.wdCountry)")
//}
// .onChange(of: orientInfo.orientation == .portrait) { newValue in
// bank.listDate = ""
// }
// if orientInfo.orientation == .portrait {
// Text("portrait")
// } else {
// Text("landscape")
// }
}
}
// check if the entry date is the 1st entry in list or the same as previous date
func ckDateStatus( cDate: Date) -> (String) {
var outDate: String = ""
// initialzie the entry date
let entryDate = cDate.formatted(.dateTime.year().day().month(.wide))
// if saved date is blank -> no previous entries
if bank.listDate.isEmpty {
outDate = entryDate
}
else { // saved date is not blank
if bank.listDate == entryDate {
outDate = ""
}
else { // date entries different
outDate = entryDate
}
}
bank.listDate = entryDate
// outDate returns blank or the current date
return (outDate)
}
}
您的方法存在的问题是 SwiftUI 仅重绘必须重绘的单元格。所以在方向改变时,不能保证所有的单元格都会被刷新。
你可以通过添加到你的外部来解决这个问题!查看:
.id(orientInfo)
这将在 orientInfo
更改时强制重绘视图。
但我会根据 pre-organizing 你的数据建议另一种方法。
您可以创建一个包含您拥有的所有唯一日期的数组,然后按该日期过滤条目。然后可以使用这些数组以您想要的方式显示您的数据——它也可以安全地处理方向变化。
struct ContentView: View {
// dummy data
let bank: [BankWithdrawal] = [
BankWithdrawal(wdDate: "22/03/01", wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: "22/03/01", wdAmount: 100, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/02", wdAmount: 300, wdCity: "Orlando", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/02", wdAmount: 150, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: "22/03/02", wdAmount: 200, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/03", wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: "22/03/04", wdAmount: 500, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: "22/03/04", wdAmount: 150, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: "22/03/04", wdAmount: 250, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: "22/03/05", wdAmount: 150, wdCity: "S.F.", wdState: "CA")
]
// creates a list of unique date entries
// (goes through all elements, saves them in a set, checks if already in set)
var uniqueBankDates: [BankWithdrawal] {
var seen: Set<String> = []
return bank.filter { seen.insert([=11=].wdDate).inserted }
}
// filters entries for the given date
func bankEntries(for date: String) -> [BankWithdrawal] {
return bank.filter { [=11=].wdDate == date }
}
var body: some View {
List {
// outer ForEach with unique dates
ForEach(uniqueBankDates) { dateItem in
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem.wdDate)) { item in
Text("$\(item.wdAmount, specifier: "%.2f") \(item.wdCity), \(item.wdState)")
}
} header: {
Text(dateItem.wdDate)
}
}
}
}
}
struct BankWithdrawal: Identifiable {
let id = UUID()
var wdDate: String
var wdAmount: Double
var wdCity: String
var wdState: String
var wdCountry: String = "USA"
}
编辑:
使用 Date()
时,您可以这样做:
struct ContentView: View {
// dummy data
let bank: [BankWithdrawal] = [
BankWithdrawal(wdDate: Date(), wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: Date(), wdAmount: 100, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: Date(), wdAmount: 300, wdCity: "Orlando", wdState: "FL"),
BankWithdrawal(wdDate: Date(), wdAmount: 150, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: Date(), wdAmount: 200, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: Date(), wdAmount: 150, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 500, wdCity: "S.F.", wdState: "CA"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 150, wdCity: "Miami", wdState: "FL"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 250, wdCity: "New York", wdState: "NY"),
BankWithdrawal(wdDate: Date() + 60*60*24*1, wdAmount: 150, wdCity: "S.F.", wdState: "CA")
]
// creates a list of unique date entries
// (goes through all elements, saves them in a set, checks if already in set)
var uniqueBankDates: [String] {
var seen: Set<String> = []
return bank.filter { seen.insert([=12=].wdDate.formatted(date: .abbreviated, time: .omitted)).inserted }
.map {[=12=].wdDate.formatted(date: .abbreviated, time: .omitted) }
}
// filters entries for the given date
func bankEntries(for date: String) -> [BankWithdrawal] {
return bank.filter { [=12=].wdDate.formatted(date: .abbreviated, time: .omitted) == date }
}
var body: some View {
List {
// outer ForEach with unique dates
ForEach(uniqueBankDates, id: \.self) { dateItem in
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem)) { item in
Text("$\(item.wdAmount, specifier: "%.2f") \(item.wdCity), \(item.wdState)")
}
} header: {
Text("\(dateItem)")
}
}
}
}
}
struct BankWithdrawal: Identifiable {
let id = UUID()
var wdDate: Date
var wdAmount: Double
var wdCity: String
var wdState: String
var wdCountry: String = "USA"
}