在geometryReader中设置@State var

Ste*_*Vet 7 swiftui geometryreader

如何在 GeometryReader 中设置 @State var?

这是我的代码:

@State var isTest:Int = 0

var body: some View {
    VStack{
        ForEach(self.test, id: \.id) { Test in
            VStack{
                GeometryReader { geometry in
                    self.isTest = 1
Run Code Online (Sandbox Code Playgroud)

我尝试使用一个函数,但它不起作用。

@State var isTest: Int = 0

func testValue() {
    self.isTest = 1
}

var body: some View {
    VStack{
        ForEach(self.test, id: \.id) { Test in
            VStack{
                GeometryReader { geometry in
                    testValue()

Run Code Online (Sandbox Code Playgroud)

任何想法?谢谢!

Mad*_*yar 9

您可以使用onAppear(perform:)@State使用初始视图大小更新变量,并使用 onChange(of:perform:)在视图大小更改时更新变量:

struct MyView: View {
  @State private var size: CGSize = .zero

  var body: some View {
    GeometryReader { geometry in
      ZStack {
        Text("Hello World")
      }.onAppear {
        size = geometry.size
      }.onChange(of: geometry.size) { newSize in
        size = newSize
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Wil*_*ong 3

我昨天也遇到了类似的问题。但我试图从 GeometryReader 内部传递一个值。

我尝试了几种方法,但没有成功。当我用来@State var声明变量时,编译器再次以紫色线抱怨说,在更新期间修改视图将使其变为未定义。

当我尝试var仅使用声明变量时,编译器只是告诉我它是不可变的。

然后,我尝试将其存储到我的@EnvironmentObject. 我刚刚遇到了死循环。

所以,我最后的希望是使用通知方式及其工作原理。但我不知道这是否是标准的实施方式。

@State private var viewPositionY:CGFloat = 0
Run Code Online (Sandbox Code Playgroud)

首先,通过通知发布值frame.origin.y

 GeometryReader{ geometry -> Text in
        let frame = geometry.frame(in: CoordinateSpace.global)
        NotificationCenter.default.post(name: Notification.Name("channelBlahblahblah"), object:nil, userInfo:["dict":frame.origin.y])
        return Text("My View Title")
 }
Run Code Online (Sandbox Code Playgroud)

然后声明一个发布者来接收通知。

private let myPublisher = NotificationCenter.default.publisher(for: Notification.Name("channelBlahblahblah"))
Run Code Online (Sandbox Code Playgroud)

最后,使用.onReceive修饰符来接收通知。

.onReceive(myPublisher) { (output) in
           
   viewPositionY = output.userInfo!["dict"] as! CGFloat
   //you can do you business here
}
Run Code Online (Sandbox Code Playgroud)