UIScrollView是iOS开发中经常用到的UI控件,像图片轮播之类的效果都可以用UIScrollView来实现,当然轮播什么的网上有很多教程了,我就不多说了。今天主要讲三个跟交互有关的效果(稍微有点标题党啊,其实也没有多进阶……),也不是直接用的UIScrollView,而是它的子类UITableView和UIWebView。先看一下效果图吧,都来自我自己的项目:
先看第一个,是个挺常用的效果。列表上面是三个栏目按钮和轮播图片,向上滚动时,按钮和图片一起向上,按钮周边区域颜色渐变,然后在到指定位置时(这里是盖住导航栏之后)按钮停住不动,周边颜色也完全变成导航栏的颜色,列表数据还可以继续滚动。这个要怎么实现呢?其实也挺简单,重点是 contentInset
这个属性。这个属性是UIScrollView的,用来指定内容边界,UITableView继承自UIScrollView,当然也含有这个属性。
tableView.contentInset.top = tableViewInsetTop
tableViewInsetTop
是我定义的一个常量,这句代码指定tableView里的实际内容离tableView整个frame的顶部距离为tableViewInsetTop
。这段距离用来放图片和栏目按钮。然后就是在 scrollViewDidScroll
这个委托方法中做一点处理:
func scrollViewDidScroll(scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
if -offsetY > menuBtnH - barHeight {
//按钮未到指定位置前,图片与按钮都跟随滑动
menuBtnsView.frame.origin.y = -offsetY - menuBtnH + topBorder
imageSlider.frame.origin.y = -(TableViewInsetTop + offsetY) + focusImageY
//透明度渐变
let alphaValue = 1 + (offsetY + menuBtnH) / (focusImageH/2)
menuBtnsView.backgroundColor = UIColor.navigationBarColor(alphaValue)
} else if menuBtnsView.frame.origin.y != statusHeight {
//防止滑动过快导致控件停留在错误的位置
menuBtnsView.frame.origin.y = statusHeight
imageSlider.frame.origin.y = -focusImageH
menuBtnsView.backgroundColor = UIColor.navigationBarColor()
}
}
稍微说明一下,offsetY
是UITableView里的内容在Y轴上的偏移量。因为之前设置了contentInset
,所以这个offsetY
一开始是等于-TableViewInsetTop
的。menuBtnH
是栏目按钮的高,barHeight
是导航栏的高。我要做的效果是栏目按钮得盖住导航栏,所以按钮要在-offsetY = menuBtnH - barHeight
的时候才会停下。感兴趣的同学可以看一下我单独为这个效果写的一个简单Demo,clone下来自己跑一下,琢磨琢磨应该就明白了。
第二个效果是拉出一个按钮,按钮的背景色也是由浅入深渐变,拉出来之后按钮就停在顶部,然后刷新图标(旋转小菊花)会在按钮下面显示。这个其实也很简单,主要就是在完全拉出按钮之后改变contentInset
:
//Mark: - Table view delegate(下拉显示提问按钮)
override func scrollViewDidScroll(scrollView: UIScrollView) {
let offsetY = -scrollView.contentOffset.y
if offsetY < maxH {
//按钮淡入效果
askBtn.askLabel.alpha = offsetY/maxH
return
}
if btnShow {
//按钮停留顶部
askBtn.frame.origin.y = -offsetY
return
}
tableView.contentInset.top = maxH
self.refreshControl = refreshCtrl
askBtn.askLabel.alpha = 1
btnShow = true
}
没太多可说的,继续第三个效果吧。第三个效果就不是TableView了,而是个WebView,效果是向上滑动时隐藏底栏,向下时显示底栏。重点是判断WebView的滑动方向:
extension WebViewCtrl: UIScrollViewDelegate {
//判断当前是向上还是向下滑动
func scrollViewDidScroll(scrollView: UIScrollView) {
newY = scrollView.contentOffset.y
if newY > oldY {
scrollDirection = .Up
} else if oldY > newY {
scrollDirection = .Down
}
//更新y轴偏移量
oldY = newY
}
}
scrollDirection
的类型是自己定义的一个枚举:
enum ScrollDirection {
case Up
case Down
case None
}
具体的实现可以看看我之前写的这个CustomWebView,原理是一样的,只不过把底栏换成了收藏按钮。
嗯,有什么问题欢迎评论。