最近实现了下tableViewCell视觉差效果,分享一波。
原理
<pre>自定义cell,需要一张大于contentView的图片,并且设置好相应约束。
coverImageView 和 centerYConstraint 作为 IBOutlet。
在tableView滚动的时候通过协议方法向cell发送通知,cell收到消息改变constraint实现效果。</pre>
具体实现
//需要使用到的成员变量
@IBOutlet weak var tableView: UITableView!
var dataArray:NSMutableArray = NSMutableArray()
var once:dispatch_once_t = 0
var lastPoint:CGPoint = CGPoint(x: 0, y: 0)
override func viewDidLoad() {
super.viewDidLoad()
//设置代理,往数据源加入数据
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.separatorStyle = .None
for index in 1...9 {
let image:UIImage = UIImage(named: "\(index).jpg")!
self.dataArray.addObject(image);
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//注册Nib
dispatch_once(&once) {
tableView.registerNib(UINib(nibName: "MyTableViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: "CELL")
}
let cell:MyTableViewCell = tableView.dequeueReusableCellWithIdentifier("CELL", forIndexPath: indexPath) as! MyTableViewCell
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
//设置高度
return 9 / 16 * UIScreen.mainScreen().bounds.size.width
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
//当需要显示cell时调用,填充数据
let cell:MyTableViewCell = cell as! MyTableViewCell
cell.coverImageView.image = self.dataArray[indexPath.row] as? UIImage
}
//通过lastPoint.y和contentOffset.y进行比较可以得出滑动方向,往cell发送通知
func scrollViewDidScroll(scrollView: UIScrollView) {
var directionStr:String = ""
if lastPoint.y > scrollView.contentOffset.y {
directionStr = "Up"
} else if lastPoint.y < scrollView.contentOffset.y {
directionStr = "Down"
}
lastPoint = scrollView.contentOffset
NSNotificationCenter.defaultCenter().postNotificationName("ScrollViewAnimation", object: directionStr)
}
//cell的成员变量
@IBOutlet weak var coverImageView: UIImageView!
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!
var constantGap:CGFloat = 0.0
override func awakeFromNib() {
super.awakeFromNib()
//剪裁掉超出cell的内容
self.contentView.clipsToBounds = true
self.clipsToBounds = true
//计算y轴中心约束可移动的最大范围绝对值
constantGap = (2/1) * self.contentView.bounds.size.width / 2 - self.contentView.bounds.size.height/2
//注册通知
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyTableViewCell.scrollViewAnimation), name: "ScrollViewAnimation", object: nil)
}
func scrollViewAnimation(notification:NSNotification) {
let directionStr:String = notification.object as! String
var constant:CGFloat = self.centerYConstraint.constant
//通过传来的参数判断滑动方向,实时改变约束值
if directionStr == "Up" {
if constant < constantGap {
constant += 1
} else if constant > constantGap {
constant = constantGap
}
self.centerYConstraint.constant = constant
} else if directionStr == "Down" {
if constant > -1 * constantGap {
constant -= 1
} else if constant < -1 * constantGap {
constant = -1 * constantGap
}
self.centerYConstraint.constant = constant
}
}
//移除通知
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}