簡要
上次做完上面的封面照片的連動
接下來下面有一個特殊的View
上滑到一定程度後
就會隨著距離
最後變成navigation bar
但我不知道是不是可以這樣
這次我是想用簡單的
使用一個View
配合和監聽scrollViewDidScroll
做變化
這裡來看一下原生Uber eat
效果
基本設置
tableView設置按照上一篇做設定
[Day 14] Swift TableView 下拉放大頂部圖片 下拉放大封面照 (上)
這裏在tableView
新增過後
在加一個topView
在上面
以及其他label
來顯示一些餐廳資訊
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.tableView)
self.view.addSubview(self.topView)
}
lazy var topView: UIView = {
//底部的View
let topView = UIView()
topView.frame = CGRect.init(x: 15, y: 100, width: KScreenWidth - 15*2, height: 200)
topView.backgroundColor = UIColor.white
//標題
titleLabel = UILabel()
titleLabel.frame = CGRect.init(x: 20, y: 25, width: topView.frame.width-20*2, height: 75)
titleLabel.font = UIFont(name: "Arial", size: 23)
titleLabel.numberOfLines = 2;
titleLabel.text = "麥當勞 S161中復興二 McDonald's Fu Sing II, Taichung"
topView.addSubview(titleLabel)
//分類
stateLabel = UILabel()
stateLabel.frame = CGRect.init(x: 20, y: titleLabel.frame.maxY, width: topView.frame.width-20*2, height: 20)
stateLabel.font = UIFont(name: "Arial", size: 13)
stateLabel.text = "美式美食・$"
topView.addSubview(stateLabel)
//其他資訊
otherLabel = UILabel()
otherLabel.frame = CGRect.init(x: 20, y: stateLabel.frame.maxY+20, width: topView.frame.width-20*2, height: 20)
otherLabel.textColor = UIColor.darkGray
otherLabel.font = UIFont(name: "Arial", size: 13)
otherLabel.text = "5-15分鐘 4.8(500+) 15.00TWD 費用"
topView.addSubview(otherLabel)
return topView
}()
scrollViewDidScroll
scrollViewDidScroll
部分要把y
跟著滑動距離
就可以使底層View
跟著滑動
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let radius = -offsetY/200
if (-offsetY > 200){
headImageView.transform = CGAffineTransform.init(scaleX: radius, y: radius)
var frame = headImageView.frame
frame.origin.y = offsetY
headImageView.frame = frame
}
//本篇新增
let topViewX:CGFloat = 15*radius
topView.frame = CGRect.init(x: topViewX, y: 100-200-offsetY, width: KScreenWidth - topViewX*2, height: 200)
}
Demo
但要符合原生APP
還需要三點
– 滑動時 根據滑動距離連動透明度(漸變)
– 標題行數會從2行 變成 1行
– 標題會移動到中間
– 底層View滑動到頂部會有一半會在上面停住
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let radius = -offsetY/200
if (-offsetY > 200){
headImageView.transform = CGAffineTransform.init(scaleX: radius, y: radius)
var frame = headImageView.frame
frame.origin.y = offsetY
headImageView.frame = frame
}
let topViewX:CGFloat = 15*radius
if radius > 0 {
titleLabel.frame = CGRect.init(x: 20, y: 25 + (105*(1-radius)), width: topView.frame.width-20*2, height: 75)
stateLabel.frame = CGRect.init(x: 20, y: titleLabel.frame.maxY, width: topView.frame.width-20*2, height: 20)
otherLabel.frame = CGRect.init(x: 20, y: stateLabel.frame.maxY+20, width: topView.frame.width-20*2, height: 20)
stateLabel.alpha = radius
otherLabel.alpha = radius
topView.frame = CGRect.init(x: topViewX, y: 100-200-offsetY, width: KScreenWidth - topViewX*2, height: 200)
titleLabel.numberOfLines = 2;
}else{
stateLabel.alpha = 0
otherLabel.alpha = 0
titleLabel.numberOfLines = 1;
}
}
這樣根據radius
來判斷是否已經超過頂部
並且來控制alpha慢慢變化
到頂部的時候記得把標題numberOfLines
改變為1
並且標題的y
也要快速移動
到定點
就這樣來看看完成品
Demo
Github
https://github.com/Bgihe/TableViewHeaderTest