弹出框在 ForEach 中显示不准确的信息
Posted
技术标签:
【中文标题】弹出框在 ForEach 中显示不准确的信息【英文标题】:Popover displaying inaccurate information inside ForEach 【发布时间】:2021-02-07 00:52:28 【问题描述】:我在 NavigationView 中有一个 ForEach 循环时遇到了问题。当我单击编辑按钮,然后单击每一行右侧的铅笔图像时,我希望它显示我们在 ForEach 循环中使用的文本变量。但是当我点击 test123 以外的文本的铅笔图像时,它仍然显示文本 test123,我完全不知道为什么。
Here's 一个视频。为什么会这样?
import SwiftUI
struct TestPopOver: View
private var stringObjects = ["test123", "helloworld", "reddit"]
@State private var editMode: EditMode = .inactive
@State private var showThemeEditor = false
@ViewBuilder
var body: some View
NavigationView
List
ForEach(self.stringObjects, id: \.self) text in
NavigationLink( destination: HStackText("Test!"))
HStack
Text(text)
Spacer()
if self.editMode.isEditing
Image(systemName: "pencil.circle").imageScale(.large)
.onTapGesture
if self.editMode.isEditing
self.showThemeEditor = true
.popover(isPresented: $showThemeEditor)
CustomPopOver(isShowing: $showThemeEditor, text: text)
.navigationBarTitle("Reproduce Editing Bug!")
.navigationBarItems(leading: EditButton())
.environment(\.editMode, $editMode)
struct CustomPopOver: View
@Binding var isShowing: Bool
var text: String
var body: some View
VStack(spacing: 0)
HStack()
Spacer()
Button("Cancel")
self.isShowing = false
.padding()
Divider()
List
Section
Text(text)
.listStyle(GroupedListStyle())
【问题讨论】:
【参考方案1】:这是一个非常常见的问题(尤其是自 ios 14 以来),sheet
会遇到很多问题,但也会影响popover
。
您可以使用popover(item:)
而不是isPresented
来避免它。在这种情况下,它实际上会使用最新的值,而不仅仅是在查看第一次渲染或首次设置时出现的值。
struct EditItem : Identifiable //this will tell it what sheet to present
var id = UUID()
var str : String
struct ContentView: View
private var stringObjects = ["test123", "helloworld", "reddit"]
@State private var editMode: EditMode = .inactive
@State private var editItem : EditItem? //the currently presented sheet -- nil if no sheet is presented
@ViewBuilder
var body: some View
NavigationView
List
ForEach(self.stringObjects, id: \.self) text in
NavigationLink( destination: HStackText("Test!"))
HStack
Text(text)
Spacer()
if self.editMode.isEditing
Image(systemName: "pencil.circle").imageScale(.large)
.onTapGesture
if self.editMode.isEditing
self.editItem = EditItem(str: text) //set the current item
.popover(item: $editItem) item in //item is now a reference to the current item being presented
CustomPopOver(text: item.str)
.navigationBarTitle("Reproduce Editing Bug!")
.navigationBarItems(leading: EditButton())
.environment(\.editMode, $editMode)
.navigationViewStyle(StackNavigationViewStyle())
struct CustomPopOver: View
@Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
var text: String
var body: some View
VStack(spacing: 0)
HStack()
Spacer()
Button("Cancel")
self.presentationMode.wrappedValue.dismiss()
.padding()
Divider()
List
Section
Text(text)
.listStyle(GroupedListStyle())
我还选择使用presentationMode
环境属性来关闭弹出框,但您可以传递editItem
绑定并将其设置为nil
(@Binding var editItem : EditItem?
和@ 987654330@)。前者只是更惯用一点。
【讨论】:
可以确认,“isPresented”在 macOS 中只是被破坏了,而“item”几乎可以正常工作(有时只是什么都不做,但大部分时间都可以) 非常感谢。您的帮助是物有所值的!以上是关于弹出框在 ForEach 中显示不准确的信息的主要内容,如果未能解决你的问题,请参考以下文章