skip to Main Content

Hi I am working on a iOS version of a project I did for Android and I am trying to place markers/annotations on an image. I was able to get some help for the android version but I don’t really understand the math and how to do the same in SwiftUI.

Right now this is what I have setup in Swift –

import SwiftUI
import Kingfisher

struct ImageView: View {
    @StateObject var viewModel = viewModel()
    let index: Int
    @State var showSheet: Bool = false
    @State var show: Bool = false
    @State var currentAnnotationSelected: SelectedAnnotationModel?
    @State var showDialog: Bool = false
    @State var note: String = ""
    @State var localY: CGFloat = 0
    @State var globalY: CGFloat = 0
    @State var localX: CGFloat = 0
    @State var globalX: CGFloat = 0
    var annotationIndex: Int = 0
    
    var body: some View {
        VStack {
            
            KFImage.url(URL(string: viewModel.uri ?? ""))
                .placeholder {ProgressView()}
                .loadDiskFileSynchronously()
                .cacheMemoryOnly()
                .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local).onEnded { dragGesture in
                 self.localY = dragGesture.location.y
                 self.localX = dragGesture.location.x
                 showSheet = true
              })
        }
        .sheet(isPresented: $showSheet) {
            VStack {
                AnnotationNote(x: Int(self.localX), y: Int(self.localY))
            }
            .presentationDetents([.medium])
            .presentationDragIndicator(.visible)
            
        }
        .overlay {
            VStack{
                if(viewModel.annotations != [] && viewModel.annotations  != nil) {
                    
                    ForEach(Array((viewModel.annotations.enumerated())!), id: .offset) { index, annotation in
                        
                        Circle()
                            .frame(width: 15, height: 15)
                            .position(x: 100, y: 100)
                        //.position(x: CGFloat(annotation.coordinateX), y: CGFloat(annotation.coordinateY))
                            .onTapGesture {
                                currentAnnotationSelected = SelectedAnnotationModel(index: index, details: annotation)
                                self.showSheet = true
                            }
                    }
                }
            }
        }
    }
}

It’s giving me 2 issues though – 1. The markers are not showing where I clicked and 2. I need the android and iOS versions to both show the markers correctly for the same image on any device, so I’m not sure how to do those same calculations in swift? – Android Version

2

Answers


  1. try this

    import SwiftUI
    import Kingfisher
    
    struct ImageView: View {
        @StateObject var viewModel = viewModel()
        @State var showSheet: Bool = false
        @State var currentAnnotationSelected: SelectedAnnotationModel?
        @State var localX: CGFloat = 0
        @State var localY: CGFloat = 0
        @State var imageSize: CGSize = .zero // To store the size of the image
        @State var annotations: [AnnotationModel] = [] // To store all annotations
        
        var body: some View {
            VStack {
                GeometryReader { geometry in
                    ZStack {
                        KFImage.url(URL(string: viewModel.uri ?? ""))
                            .placeholder { ProgressView() }
                            .loadDiskFileSynchronously()
                            .cacheMemoryOnly()
    
    Login or Signup to reply.
  2. In SwiftUI, the image may be scaled to fit within a Image view, and its displayed size might not match the original size. Also note SwiftUI positions elements relative to their parent view. The markers are placed relative to the scaled image size.

    Adding ZStack to image or adjusting scaling factor should help.
    try resizable() and scaledToFit()

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search