2

我正在使 Swift 项目适应 SwiftUI。原始项目对 UIImages 进行拖放、绘图和其他一些在 SwiftUI 中无法实现的操作。

下面的代码仅用于解释问题。工作代码: https ://github.com/rolisanchez/TestableDragAndDrop

在该项目中,当用户点击一个按钮时,a@State setChooseImage变为 true,打开一张工作表,其中向他展示了一系列图像:

.sheet(isPresented: self.$setChooseImage, onDismiss: nil) {
                        VStack {
                            Button(action: {
                                self.setChooseImage = false
                                self.chosenAssetImage = UIImage(named: "testImage")
                                self.shouldAddImage = true
                            }) {
                                Image("testImage")
                                    .renderingMode(Image.TemplateRenderingMode?.init(Image.TemplateRenderingMode.original))

                                Text("Image 1")
                            }
                            Button(action: {
                                self.setChooseImage = false
                                self.chosenAssetImage = UIImage(named: "testImage2")
                                self.shouldAddImage = true
                            }) {
                                Image("testImage2")
                                    .renderingMode(Image.TemplateRenderingMode?.init(Image.TemplateRenderingMode.original))
                                Text("Image 2")
                            }
                        }
                }

选择图像后,setChooseImage设置回false,关闭工作表。图像self.chosenAssetImage也是一个@State并设置为所选图像。@State shouldAddImage也设置为真。这个选择的 UIImage 和 Bool 在我创建的 UIView 中使用,以添加 UIImages。它在 SwiftUI 中是这样调用的:

 DragAndDropRepresentable(shouldAddImage: $shouldAddImage, chosenAssetImage: $chosenAssetImage)

添加 UIView 的 UIViewRepresentable 如下:

struct DragAndDropRepresentable: UIViewRepresentable {
    @Binding var shouldAddImage: Bool
    @Binding var chosenAssetImage: UIImage?

    func makeUIView(context: Context) -> DragAndDropUIView {
        let view = DragAndDropUIView(frame: CGRect.zero)
        return view
    }

    func updateUIView(_ uiView: DragAndDropUIView, context: UIViewRepresentableContext< DragAndDropRepresentable >) {
        if shouldAddImage  {
            shouldAddImage = false
            guard let image = chosenAssetImage else { return }
            uiView.addNewAssetImage(image: image)
        }
    }
}

我知道updateUIView只要有一些可能影响视图的更改就会调用。在这种情况下,shouldAddImage 变为 true,从而正确进入if循环并调用 addNewAssetImage,将图像插入 UIView。

这里的问题是在更新绑定之前updateUIView被多次调用,并且一直进入if shouldAddImage循环。shouldAddImage这意味着它将多次将图像添加到 UIView。

我在赋值之前和之后都放了一个断点shouldAddImage = false,甚至在通过那一行之后,值仍然是true

我想要的行为是将shouldAddImage立即更改为false,这样即使updateUIView被多次调用,它也只会进入循环一次,只添加一次图像。

4

0 回答 0