TLDR:在下面的代码中,单击顶层 ContentView 中的按钮会打开多个工作表,然后在关闭工作表时再次触发;但从 RowView 中单击它只会打开一张表。如何只从 ContentView 打开一张纸?
这是我所拥有的一个简单版本:带有项目列表的导航堆栈,每个项目都有一个可打开工作表的按钮。当拉出工作表时,它会运行一个任务来调用 Web 服务并检索一些要显示的数据。
问题是,根据我的调试,正在打开多个工作表,每个工作表都运行任务,并且有些工作表由于重复调用而失败。我想解决这个问题的方法是让工作表只出现一次。我怎样才能让它发挥作用?
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
List {
NavigationLink {
Text("Hello")
} label: {
RowView(textToShow: "Text 1")
}
NavigationLink {
Text("Hello")
} label: {
RowView(textToShow: "Text 2")
}
}
}
}
}
struct RowView: View {
var textToShow: String
@State private var showingPopover = false
var body: some View {
Text("Hello")
Button(action: {
//showingPopover = true
print("Button pressed")
}, label: {
Image(systemName:"doc.text")
.imageScale(.large)
})
.onTapGesture {
print("Button tapped")
showingPopover = true
}
.sheet(isPresented: $showingPopover, content: {
PopupView(textToShow: textToShow)
.onAppear {
print("Sheet appeared")
}
})
}
}
struct PopupView: View {
var textToShow: String
@State private var loading = true
var body: some View {
VStack {
if loading {
HStack{
ProgressView()
Text("Loading...")
}
} else {
Text(textToShow)
}
}
.onAppear() {
print("Loading")
loading = false
}
}
}
#Preview {
ContentView()
}
#Preview {
RowView(textToShow: "Text 1")
}
单击按钮,然后关闭工作表会在控制台中显示以下内容:
轻按按钮
加载中
表格出现了
加载中
表格出现了
加载中
表格出现了
我尝试使用状态变量来捕获弹出窗口何时已打开,然后仅在弹出窗口尚未打开时才显示工作表内容;我尝试仅在第一次点击手势时将绑定变量设置为
true
,但这也不是解决办法。
基于另一个类似的问题,我认为我需要将工作表向上移动,这对于捕获特定于行的文本来说有点棘手(我现在已经使用 swift 大约两周了?所以还没有完全习惯它)但我认为这可行
我期望只用一张表来加载并运行其任务。
好吧,我想我找到了一个解决方案:通过将工作表移动到导航堆栈,它只出现一次。为了使注释来自与行相关的变量,我只使用绑定变量。在本例中,我使用了
isPresented
和一个单独的变量,但在我自己的情况下,我想我将使用 item
输入作为工作表。
import SwiftUI
struct ContentView: View {
@State var showingPopover: Bool = false
@State var textToShow: String = ""
var body: some View {
NavigationStack {
List {
NavigationLink {
Text("Hello")
} label: {
RowView(showingPopover: $showingPopover, textToShow: $textToShow, textValue: "Text 1")
}
NavigationLink {
Text("Hello")
} label: {
RowView(showingPopover: $showingPopover, textToShow: $textToShow, textValue: "Text 2")
}
}
}
.sheet(isPresented: $showingPopover, onDismiss: {
print("Sheet dismissed")
showingPopover = false
textToShow = ""
}, content: {
PopupView(textToShow: textToShow)
.onAppear {
print("Popup appeared")
}
})
}
}
struct RowView: View {
@Binding var showingPopover: Bool
@Binding var textToShow: String
var textValue: String
var body: some View {
Text("Hello")
Button(action: {
//showingPopover = true
print("Button pressed")
}, label: {
Image(systemName:"doc.text")
.imageScale(.large)
})
.onTapGesture {
print("Button tapped")
textToShow = textValue
showingPopover = true
}
}
}
struct PopupView: View {
var textToShow: String
@State private var loading = true
var body: some View {
VStack {
if loading {
HStack{
ProgressView()
Text("Loading...")
}
} else {
Text(textToShow)
}
}
.onAppear() {
print("Loading")
loading = false
}
}
}
#Preview {
ContentView()
}