【发布时间】:2015-09-20 22:45:49
【问题描述】:
这是一个简单的 Swift 扩展,用于 UILabel,
let dur=0.1 // (set to say 2.0 to see the effect more clearly)
extension UILabel
{
func change(s:String)->()
{
print("attempting 'change' with \(s)")
UIView.animateWithDuration( dur,
animations: { self.alpha = 0.2 },
completion:
{ _ in
self.text = s ///CCC
UIView.animateWithDuration( dur,
animations: { self.alpha = 1.0 })
})
}
}
使用 UILabel,只需这样做
aLabel.change("hello there")
它将迅速从旧文本融合到新文本。没问题。
当然,如果我们能写这个就更好了……
aLabel.text = "hello there"
为此,只需创建一个新的 UILabel 类,并使用新版本的“.text”属性。
class CoolLabel:UILabel
{
override var text:String?
{
get { return super.text }
set { super.change(newValue!) } //PROBLEM! AAA
}
}
但是!它不起作用:它进入一个无限循环。
注意 change() 扩展中的“self.text”:此时它进入一个循环。
(我也试过set { self.change(newValue!) },还是不行。)
以下工作完美:
class TOLabel:UILabel
{
override var text:String?
{
get { return super.text }
set
{
UIView.animateWithDuration( dur,
animations: { self.alpha = 0.2 },
completion:
{ _ in
super.text = newValue //BBB
UIView.animateWithDuration( dur,
animations: { self.alpha = 1.0 })
})
}
}
}
这很好,但我在第一个版本中做错了什么?
您将如何编写设置器以成功使用 .change 扩展名?
顺便说一句,对于阅读此处的任何人来说,您将如何更充分地继承 IBLabel,您必须覆盖指定的初始化程序,并且您需要保留本地“实时”版本的文本,以便 getter 正确回复在动画期间,在您设置文本之后立即进行。
class TOLabel:UILabel
{
private var _text:String?
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
self._text = super.text;
}
override var text:String?
{
get { return self._text }
set {
self._text = newValue;
UIView.animateWithDuration( dur,
animations: { self.alpha = 0.2 },
completion:
{ _ in
super.text = self._text
UIView.animateWithDuration( dur,
animations: { self.alpha = 1.0 })
})
}
}
}
【问题讨论】:
-
这是您需要绕过 setter 的实例之一。您需要在更改方法中使用
super.text,就像在上一个代码示例中一样。 -
但事情是这样的。在我的评论
//PROBLEM中,我确实将 SUPER 发送到“改变”。但是当change在change的第6行运行时,它是在TOLabel上运行的,而不是在super... :O -
对。您遇到的问题是您无法绕过setter,因此无法避免递归。老实说,无论如何,子类可能是更好的方法。
-
嗯,我相信你,但我不明白为什么我可以在 BBB 上说“super.text=”,但我不能在 CCC 上说 super.text,在 AAA 上拨打
change. -
因为当您在子类的上下文中执行代码时,super.text 不会调用您的子类设置器。当您执行
change时,它会调用self.text的设置器,这是子类设置器,这会导致递归。如果你在你的子类(它可能属于它)中实现更改,你可以使用super.text,你不会有问题
标签: ios swift properties