0

I'm trying to implement the box with the fixed aspect ratio that helps user to frame the image before it gets cropped. They may zoom in/out and move the image but the container must stay filled.

I'm struggling with blocking an (arbitrary) image from being dragged to the left (or to the top) to the point when only part of it stays in container, i.e. if a user loads vertical image, the horizontal scroll should not work until they zoom in, but if it's a horizontal image then the vertical scroll should not work. However, when the image is zoomed in.

Here is the code that I'm trying to use (that doesn't work since the key dimensions are missing).

struct ZoomableImageView: View {
    @Binding var image: Image?

    @State private var scale: CGFloat = 1.0
    @State private var lastScaleValue: CGFloat = 1.0
    
    @State private var offset: CGSize = CGSize.zero
    @State private var draggedSize: CGSize = CGSize.zero

    var body: some View {
        GeometryReader { reader in
            image?
                .resizable()
                .scaledToFill()
                .scaleEffect(self.scale)
                .offset(x: self.offset.width, y: self.offset.height)
                .gesture(
                    MagnificationGesture()
                        .onChanged { (scale) in
                            self.scale = max(scale.magnitude * self.lastScaleValue, 1.0)
                        }.onEnded { _ in
                            self.lastScaleValue = self.scale
                        })
                .simultaneousGesture(
                    DragGesture(minimumDistance: 0, coordinateSpace: .global)
                        .onChanged({ value in
                            // It should be -(image.width - reader.size.width) so the scroll is blocked when there's no more content
                            self.offset.width = max(min(value.translation.width + draggedSize.width, 0), -reader.size.width) 
                            self.offset.height = max(min(value.translation.height + draggedSize.height, 0), -reader.size.height)
                        })
                        .onEnded({ value in
                            draggedSize = self.offset
                        })
                )
        }
    }
}

In this code, reader.size is a block that is actually visible on the screen and says nothing about the underlying image. Is it possible to access the actual size of image in runtime (or put it into a state var during the load)?

  • where does the image come from originally? if it has been an `UIImage` before, you can just use `.size`on that. If not, maybe this helps: https://stackoverflow.com/questions/57028484/how-to-convert-a-image-to-uiimage – ChrisR Jan 31 '22 at 23:49

0 Answers0