15.8 C
London
Sunday, June 9, 2024

ios – UIImageView Pinch Gesture not working when wraped in SwiftUI


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
    }
}

Latest news
Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here