How to dynamically get view's origin in swiftui

450 views Asked by At

Background

Using SwiftUI, I want to implement tutorial(Coach marks) functionalities for some view( like button, text, image and so on) which was defined without specifying origin and sizes
for modifier frame. especially such functionalities will be asked for several difference screen.

My Test Code

1. Definition of PreferenceKey

struct MyPreferenceKey: PreferenceKey {
    static var defaultValue: CGRect = .zero
    static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
        value = nextValue()
    }
}
  1. main view
struct ContentView: View {
    
    @State var rating : Int = 3
    var body: some View {
        GeometryReader { geometry in
            let origin = geometry.frame(in: .global).origin
            let size = geometry.frame(in: .global).size
            VStack {

                HStack{
                    Text("Test1")   // for testing following target,just add some view hierachy
                        .padding()
                        .background(Color.yellow)
                    VStack{
                        Text("test2")
                            .padding()
                            .background(Color.purple)
                        Text("")   // here is my target, i want to get the origin of this view
                            .frame(width: 100, height: 200)   // just for having spece to show value of frame
                            .background(Color.green)
                            .overlay(
                                GeometryReader { proxy in
                                    let frm = proxy.frame(in: .global)
                                    let size = proxy.size
                                    Color.clear.preference(key: MyPreferenceKey.self,value: proxy.frame(in: .global))
                                    Text(verbatim: "X=\(String(format: "%.2f",  frm.midX)) y=\(String(format: "%.2f",  frm.midY) ) width=\(String(format: "%.2f",  frm.width)) height=\(String(format: "%.2f",  frm.height))")
                                        
                                }
                               
                            )
                    }
                }
                .onPreferenceChange(MyPreferenceKey.self){
                    print("\($0)")
                }
                
            }
            .frame(width: 200, height: 300, alignment: .center)
        }
        
    }
}

3. Ran result (Xcode)

enter image description here

4.Ran result (Log)

(89.83333333333331, 127.16666666666669, 100.0, 200.0)

5. Problem

the view with green background says it's origin.x is 139, but logs printed above is 89 in modifier onPreferenceChange.

My Question:

  1. how can i get real origin.x with 139 using like modifier onPreferenceChange.
  2. is there a way to get value shown by above Text view

thanks.

0

There are 0 answers