将变量设置为等于视图的框架,而当视图的框架更改时,值不会更改

Set a variable equal to a view's frame without the value changing when view's frame changes

我想知道一个帧在改变之前的原始值。为此,我想到了:

var baseViewOriginalFrame: CGRect!

func changeFrame() {
   baseViewOriginalFrame = boxView.frame
   boxView.transform = CGAffineTransform.identity.translatedBy(x: 0, y: +5)
}

我注意到原始帧实际上是boxView的当前帧,所以我阅读,了解到originalFrame变量只是存储了对象的位置。

那么我该如何实现(保存boxView的原始框架)?

这归结为 reference 类型和 value 类型之间的差异。

在 Swift 中,当您有一个值类型的变量(link Ints、Strings 等)时,该变量将保存该值。当你有一个引用类型的变量时(例如 Class),那么它会在内存中保存对该对象的 引用

这意味着当您传递值类型变量时,您传递的是该变量包含的实际数据。但是当你传递一个引用类型变量时,你传递的是对该对象的引用。

看下面的代码片段,你可以看到当你复制一个值类型时,你得到了它的一个实际副本。当你复制一个引用类型时,你只是得到另一个对内存中同一个对象的引用,这意味着任何变化都会反映在另一个变量中,因为它们都引用同一个对象.

// Structs are a VALUE type
struct myStruct {
    var value: Int

    init(x: Int) {
        self.value = x
    }
}

// Classes are a REFERENCE type
class myClass {
    var value: Int

    init(x: Int) {
        self.value = x
    }
}

var a = myStruct(x: 5)
var originalA = a       // This has made a copy of a, and stores it in originalA
a.value = 100

print(originalA.value)
print(a.value)

var b = myClass(x: 5)
var originalB = b       // This is still referencing the same object as the variable b.
b.value = 100

print(originalB.value)
print(b.value)

现在至于你的具体例子,我很困惑为什么它不起作用,因为据我所知,CGRect 是一个结构,它是一个值类型,所以按照你的方式制作副本应该工作正常。事实上,我只是在我的一个应用程序中的一个方法的末尾添加了你必须的代码,它的工作完全符合你的预期:

let x = textView.frame
textView.transform = CGAffineTransform.identity.translatedBy(x: 0, y: +5)
print(x)   // Prints (16.0, *83.0*, 343.0, 564.0)
print(textView.frame) // Prints (16.0, *88.0*, 343.0, 564.0)

希望这对您有所帮助, 雅各布.