我正在将Swift项目改编为SwiftUI。原始项目在UIImages,绘图和其他一些操作上具有拖放功能,而这在SwiftUI中是不可能的。
下面的代码仅用于解释问题。工作代码: https://github.com/rolisanchez/TestableDragAndDrop
在项目上,当用户单击按钮时,@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
也设置为true。我创建的用来添加UIImage的UIView中使用了所选的UIImage和Bool。在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
,它也只会进入循环一次,仅添加一次图像。