在SwiftUI中布局后,如何获取“视图”的位置?

时间:2019-06-09 21:16:04

标签: ios swift swiftui

是否有一种方法可以在布局后获取View的帧?在布局放置后,我想画一条线连接两个视图:

enter image description here

似乎我在React中需要measure之类的东西。

2 个答案:

答案 0 :(得分:4)

使用GeometryReader获取每个视图的框架,并使用该框架确定两个视图之间路径的点。

struct ContentView : View {
    var body: some View {
        GeometryReader { geometry -> Text in
            let frame = geometry.frame(in: CoordinateSpace.local)
            return Text("\(frame.origin.x), \(frame.origin.y), \(frame.size.width), \(frame.size.height)")
        }
    }
}

答案 1 :(得分:3)

要导出“渲染的”视图坐标,我为x,y坐标创建了一组数组,并将它们保存在Model对象中。但是,我不必将它们封装在@Published var中,而是将它们保留为“ var”,否则您将陷入无限循环,需要更新坐标,然后重新渲染视图。

使用Apple的“地标”教程,对Model对象进行了如下修改:

import SwiftUI
import Combine

final class UserData: ObservableObject {
  @Published var showFavoritesOnly = false
  @Published var landmarks = landmarkData
 var circleImageX = Array(repeating: 0.0, count:20)
 var circleImageY = Array(repeating: 0.0, count:20)

}

然后,每次使用以下代码渲染CircleImage.swift时,都要再次写入这些数组,同样来自“ landmark.swift”教程,以保存框架中点。

import SwiftUI

struct CircleImage: View {
  @EnvironmentObject var userData: UserData
  var landmark: Landmark

  var landmarkIndex: Int {
    userData.landmarks.firstIndex(where: {$0.id == landmark.id})!
  }
  var body: some View {

    ZStack {
      landmark.image
        .clipShape(Circle())
        .overlay(Circle().stroke(Color.white, lineWidth: 4))
        .shadow(radius: 10)
      VStack {

        GeometryReader { geometry -> Text in
          let frame = geometry.frame(in: CoordinateSpace.global)
          self.userData.circleImageX[self.landmarkIndex] = Double(frame.midX)
          return
            Text("\(frame.midX)")
              .foregroundColor(.red)
              .bold()
              .font(.title)
        }
        .offset(x: 0.0, y: 50.0)
        GeometryReader { geometry -> Text in
          let frame = geometry.frame(in: CoordinateSpace.global)
          self.userData.circleImageY[self.landmarkIndex] = Double(frame.midY)
          return
            Text("\(frame.midY)")
              .foregroundColor(.red)
              .bold()
              .font(.title)
        }
        .offset(x: 0.0, y: -50.0)
      }
    }
  }
}`

这不仅可以保存渲染的坐标,还可以将它们渲染为文本视图(如Jake建议的那样,覆盖有图像)。 自然,您可以在满意坐标正确后删除“文本覆盖”视图。 希望对您有帮助