最近實現了下tableViewCell視覺差效果,分享一波。
效果圖.gif
原理
圖1.png
<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)
}