【问题标题】:How to assign value to a variable that's 'Get-Only'?如何为“仅获取”的变量赋值?
【发布时间】:2020-02-15 21:54:31
【问题描述】:

我是 Swift 和 SwiftUI 的新手。当前,当用户捏缩放时,图像在完成后会返回到常规位置。我想要它,以便当用户停止放大图片时,它会保持放大状态。

struct ContentView: View {
   @GestureState var magnifyBy = CGFloat(1.0)
   @State var zoomIn = CGFloat(1.0)

    var magnification: some Gesture {
           MagnificationGesture()
               .updating($magnifyBy) { currentState, gestureState, transaction in
                gestureState = currentState
           }.onEnded{value in
               magnifyBy = value
        }
    }

    var body: some View {
           Circle()
               .frame(width: 100 * magnifyBy,
                      height: 100 * magnifyBy,
                      alignment: .center)
       }
}

magnifyBy = 值

给我一​​个错误: 无法分配给属性:“magnifyBy”是一个只能获取的属性

我能做些什么来解决这个问题?

【问题讨论】:

    标签: ios swift swiftui


    【解决方案1】:

    GestureState 在手势处于活动状态时处于活动状态,并且必须仅在此时间范围内使用,并相应更新。手势完成后,相应的手势状态被重置为初始值。因此,要使更改持久化,我们需要单独存储它。

    这是可能的方法(经过测试并适用于 Xcode 11.2 / iOS 13.2)

    struct ContentView: View {
        @GestureState var magnifyBy = CGFloat(1.0)
        @State var zoomIn = CGFloat(1.0)
    
        var magnification: some Gesture {
            MagnificationGesture()
                .updating($magnifyBy) { value, gestureState, transaction in
                    gestureState = value // gestureState is magnifyBy
            }.onEnded{ value in
                self.zoomIn *= value // < preserve last changes
            }
        }
    
        var body: some View {
            Circle()
                .frame(width: 100 * magnifyBy * zoomIn, //after onEnded magnifyBy=1 again
                       height: 100 * magnifyBy * zoomIn,  
                       alignment: .center)
                .gesture(magnification)
        }
    }
    

    有关GestureState 的详细信息,请参阅Apple 官方文章Adding Interactivity with Gestures。文档齐全且良好的罕见情况。

    【讨论】:

      【解决方案2】:

      这里的另一个答案将我引向了正确的方向,但我有一个棘手的交互,我需要更新 @StateObject,因此无法在 View 中进行乘法运算。对我来说,诀窍是延迟初始化@GestureState。如果这对其他人有帮助:

      @StateObject var orbit: OrbitControls = OrbitControls() // Object I need to manipulate
      @GestureState var preValue: (Float, Float)? = nil // (start, multiply)
      var zoomGesture: some Gesture {
          MagnificationGesture()
              .updating($preValue) { value, gestureState, transaction in
                  if gestureState == nil {
                      gestureState = (orbit.radius, Float(value))
                  } else {
                      gestureState = (gestureState!.0, Float(value))
                  }
                  
              }.onChanged { value in
                  guard let (start, mult) = preValue else {
                      return
                  }
                  orbit.radius = start * mult // sync object state
              }
      }
          
      

      【讨论】:

        猜你喜欢
        • 2021-11-13
        • 2023-01-20
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        • 2018-03-03
        • 2010-10-15
        • 2013-04-28
        • 1970-01-01
        相关资源
        最近更新 更多