Привязка не обновляется сразу внутри updateUIView в UIViewRepresentable - PullRequest
0 голосов
/ 17 февраля 2020

Я адаптирую проект 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 и Bool используются внутри UIView, который я создал, чтобы добавить UIImage. Он вызывается внутри SwiftUI следующим образом:

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

UIViewRepresentable для добавления UIView выглядит следующим образом:

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 стало истинным, таким образом, правильно введя if l oop и вызвав addNewAssetImage, который вставляет изображение в UIView.

Проблема здесь в том, что updateUIView вызывается несколько раз и вводит if shouldAddImage l oop все это время до обновления shouldAddImage Binding. Это означает, что он добавит изображение несколько раз в UIView.

Я установил точку останова до и после присвоения shouldAddImage = false, и даже после прохождения этой строки значение по-прежнему будет true.

Мне нужно было сразу изменить значение shouldAddImage на false, чтобы, даже если updateUIView вызывалось несколько раз, он вводил бы l oop только один раз, добавляя изображение только один раз.

...