It looks as if SwiftUI is getting/setting the body
of the picture view, which is one thing one mustn’t do when the view’s remodel
is just not the id remodel. From body
,
If the
remodel
property is just not the id remodel, the worth of this property is undefined and due to this fact ought to be ignored.
Adjustments to this property might be animated. Nonetheless, if the
remodel
property accommodates a non-identity remodel, the worth of the body property is undefined and shouldn’t be modified.
In fact, SwiftUI does not care that the view has been remodeled, and units the body
regardless, most likely to replace the body of the view in response to SwiftUI’s personal structure guidelines.
Wrapping the UIImageView
inside one other view solves this drawback.
class Wrapper: UIView {
let imageView: UIImageView
var picture: UIImage? {
get { imageView.picture }
set { imageView.picture = newValue }
}
override init(body: CGRect) {
imageView = UIImageView()
tremendous.init(body: body)
addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: topAnchor),
imageView.bottomAnchor.constraint(equalTo: bottomAnchor),
imageView.leftAnchor.constraint(equalTo: leftAnchor),
imageView.rightAnchor.constraint(equalTo: rightAnchor),
])
}
required init?(coder: NSCoder) {
fatalError()
}
}
struct UIImageViewRepresentable: UIViewRepresentable {
let picture: UIImage?
func makeCoordinator() -> Coordinator {
Coordinator()
}
@MainActor
class Coordinator: NSObject {
@objc func handlePinchGesture(_ sender: UIPinchGestureRecognizer) {
guard let view = sender.view else { return }
let scaleResult = sender.view?.remodel.scaledBy(x: sender.scale, y: sender.scale)
guard let scale = scaleResult, scale.a > 1, scale.d > 1 else { return }
sender.view?.remodel = scale
sender.scale = 1
}
}
func makeUIView(context: Context) -> Wrapper {
let wrapper = Wrapper()
wrapper.picture = picture
wrapper.imageView.isUserInteractionEnabled = true
wrapper.imageView.addGestureRecognizer(UIPinchGestureRecognizer(goal: context.coordinator, motion: #selector(Coordinator.handlePinchGesture(_:))))
return wrapper
}
func updateUIView(_ uiView: Wrapper, context: Context) {
uiView.picture = picture
}
}