SwiftUI - 按钮正确加载视图但随后在视图之间反弹
SwiftUI - Button loads views properly but then bounces between views
很明显我做错了什么。我有如下所示的三个视图。第一个是从获取请求中填充的客户列表。每行都是一个转到客户详细信息视图的导航 link。有一个“+”按钮可以创建并保存一个新的报价对象,然后转换到报价视图。但是一旦加载,客户详细信息视图就会意外地再次加载并立即被取消到客户列表视图。
这种奇怪的行为并不一致。事情往往运作良好。而如果我把makeQuoteNumber
这个方法注释掉,问题似乎就彻底解决了。我尝试向 makeQuoteNumber
方法添加一个完成处理程序,因为它是在 Quote 视图出现之前调用的,但这没有帮助。
客户名单
List {
ForEach(customers
.filter({searchText.isEmpty ? true : //code for search bar
[=10=].custName?.localizedCaseInsensitiveContains(searchText) ?? false })) { customer in
NavigationLink(destination: CustomerDetailView(customer: customer)) {
CustomerRow(customer: customer)
}
.id(self.refreshingID) //helps refresh list when a customer is added or edited.
}
.onDelete(perform: deleteCustomer)
}
客户详细信息 - 添加按钮
VStack {
NavigationLink(destination: QuoteView(quoteNumber: quoteNumber), isActive: $showQuoteView) { EmptyView() }
Button(action: {
self.CreateNewQuote(completion: {
self.showQuoteView = true
})
}) {
Image(systemName: "plus.circle.fill")
}
}
func CreateNewQuote(completion: () -> ()) {
let newQuote = Quote(context: self.moc)
newQuote.id = UUID()
let quoteNumber = makeQuoteNumber(usingDate: Date())
newQuote.quoteNumber = quoteNumber
let title = "Quote for \(customer.custName ?? "")"
newQuote.user = user.first
newQuote.quoteTitle = title
customer.addToQuotes(newQuote)
appDelegate.saveContext()
self.quoteNumber = quoteNumber
completion()
}
func makeQuoteNumber(usingDate date: Date) -> String {
let seconds = date.dateToSeconds()
let formatter = DateFormatter()
formatter.dateFormat = "MMddyy"
let formattedDate = formatter.string(from: date)
let quoteNumber = "QQ\(formattedDate)-\(seconds)"
return quoteNumber
}
func secondsFromDate(date: Date) -> Int {
let calendar = Calendar.current
var totalSeconds = 0
let hours = calendar.component(.hour, from: date)
totalSeconds = hours * 3600
let minutes = calendar.component(.minute, from: date)
totalSeconds += minutes * 60
let seconds = calendar.component(.second, from: date)
totalSeconds += seconds
return totalSeconds
}
我可以显示报价视图的代码,但作为调试的一部分,我用简单的文本视图替换了整个视图,并且行为相同。
提供的代码不可测试,所以只是一个想法 - 尝试在一些延迟后激活 link
Button(action: {
self.CreateNewQuote(completion: {
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // or this
DispatchQueue.main.async {
self.showQuoteView = true
}
})
很明显我做错了什么。我有如下所示的三个视图。第一个是从获取请求中填充的客户列表。每行都是一个转到客户详细信息视图的导航 link。有一个“+”按钮可以创建并保存一个新的报价对象,然后转换到报价视图。但是一旦加载,客户详细信息视图就会意外地再次加载并立即被取消到客户列表视图。
这种奇怪的行为并不一致。事情往往运作良好。而如果我把makeQuoteNumber
这个方法注释掉,问题似乎就彻底解决了。我尝试向 makeQuoteNumber
方法添加一个完成处理程序,因为它是在 Quote 视图出现之前调用的,但这没有帮助。
客户名单
List {
ForEach(customers
.filter({searchText.isEmpty ? true : //code for search bar
[=10=].custName?.localizedCaseInsensitiveContains(searchText) ?? false })) { customer in
NavigationLink(destination: CustomerDetailView(customer: customer)) {
CustomerRow(customer: customer)
}
.id(self.refreshingID) //helps refresh list when a customer is added or edited.
}
.onDelete(perform: deleteCustomer)
}
客户详细信息 - 添加按钮
VStack {
NavigationLink(destination: QuoteView(quoteNumber: quoteNumber), isActive: $showQuoteView) { EmptyView() }
Button(action: {
self.CreateNewQuote(completion: {
self.showQuoteView = true
})
}) {
Image(systemName: "plus.circle.fill")
}
}
func CreateNewQuote(completion: () -> ()) {
let newQuote = Quote(context: self.moc)
newQuote.id = UUID()
let quoteNumber = makeQuoteNumber(usingDate: Date())
newQuote.quoteNumber = quoteNumber
let title = "Quote for \(customer.custName ?? "")"
newQuote.user = user.first
newQuote.quoteTitle = title
customer.addToQuotes(newQuote)
appDelegate.saveContext()
self.quoteNumber = quoteNumber
completion()
}
func makeQuoteNumber(usingDate date: Date) -> String {
let seconds = date.dateToSeconds()
let formatter = DateFormatter()
formatter.dateFormat = "MMddyy"
let formattedDate = formatter.string(from: date)
let quoteNumber = "QQ\(formattedDate)-\(seconds)"
return quoteNumber
}
func secondsFromDate(date: Date) -> Int {
let calendar = Calendar.current
var totalSeconds = 0
let hours = calendar.component(.hour, from: date)
totalSeconds = hours * 3600
let minutes = calendar.component(.minute, from: date)
totalSeconds += minutes * 60
let seconds = calendar.component(.second, from: date)
totalSeconds += seconds
return totalSeconds
}
我可以显示报价视图的代码,但作为调试的一部分,我用简单的文本视图替换了整个视图,并且行为相同。
提供的代码不可测试,所以只是一个想法 - 尝试在一些延迟后激活 link
Button(action: {
self.CreateNewQuote(completion: {
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // or this
DispatchQueue.main.async {
self.showQuoteView = true
}
})