Swift-属性观察着(willSet和didSet)
属性观察者,类似于触发器.用来监视属性的除了初始化之外的属性变化,当属性值发生改变是可以对此作出响应.有如下特点
1,不仅可以在属性值改变后触发didSet,也可以在属性值改变前触发willSet。
2,给属性添加观察者必须要声明清楚属性类型,否则编译器报错。
3,willSet可以带一个newName的参数,没有的话,该参数默认命名为newValue。
4,didSet可以带一个oldName的参数,表示旧的属性,不带的话默认命名为oldValue。
5,属性初始化时,willSet和didSet不会调用。只有在初始化上下文之外,当设置属性值时才会调用。
6,即使是设置的值和原来值相同,willSet和didSet也会被调用
使用这两个方法十分简单,我们只要在属性声明的时候添加对应的代码块,就可以对设定的值和已经设置的值进行监听了:
class MyClass {
var date: NSDate {
willSet {
let d = date
print("即将将日期从 \(d) 设定至 \(newValue)")
}
didSet {
print("已经将日期从 \(oldValue) 设定至 \(date)")
}
}
init() {
date = NSDate()
}
}
let foo = MyClass()
foo.date = foo.date.dateByAddingTimeInterval(10086)
// 输出
// 即将将日期从 2014-08-23 12:47:36 +0000 设定至 2014-08-23 15:35:42 +0000
// 已经将日期从 2014-08-23 12:47:36 +0000 设定至 2014-08-23 15:35:42 +0000
willSet
在项目中我利用willSet来发送通知
import UIKit
class XNHeadView: UIView {
private var head: UIView?
var tableHeadViewHeight: CGFloat = 0 {
willSet {
NSNotificationCenter.defaultCenter().postNotificationName(HomeTableHeadViewHeightDidChange, object: newValue)
frame = CGRectMake(0, -newValue, ScreenWidth, newValue)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
head = UIView()
head!.frame = CGRectMake(0, 0, ScreenWidth, 200)
head?.backgroundColor = UIColor.redColor()
addSubview(head!)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
tableHeadViewHeight = CGRectGetMaxY(head!.frame)
}
}
// ViewController的部分代码
NSNotificationCenter.defaultCenter().addObserver(self, selector: .homeTableHeadViewHeightDidChange , name: HomeTableHeadViewHeightDidChange, object: nil)
func homeTableHeadViewHeightDidChange(noti: NSNotification) {
collectionView!.contentInset = UIEdgeInsetsMake(noti.object as! CGFloat, 0, 0, 0)
collectionView!.setContentOffset(CGPoint(x: 0, y: -(collectionView!.contentInset.top)), animated: false)
}
效果图:
红色视图跟随collectionView一起滚动,红色视图一般是图片轮播器
<div align = center>
</div>
示例代码已经上传到Github
didSet
didSet在这里就不详细讲解了