如何为“仅获取”的变量赋值?

Posted

技术标签:

【中文标题】如何为“仅获取”的变量赋值?【英文标题】: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
           .onEndedvalue in
               magnifyBy = value
        
    

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

magnifyBy = 值

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

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

【问题讨论】:

【参考方案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
        

    

【讨论】:

以上是关于如何为“仅获取”的变量赋值?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 TensorFlow 变量赋值?

spring @Value如何为变量java赋值[关闭]

如何为变量赋值并在while循环中检查其值?

如何用SQL代码将动态查询结果赋值给变量?

如何为PLC定时器设置变量时间

ORACLE中如何为存储过程传递参数?