何曾几时,在一些热门的App的数据索引界面里,我们常常能够看到用户在改变索引时,屏幕中心会有索引的放大显示,非常人性化。
在这一篇博文里,本猫就来尝试用尽可能简单的代码来完成这一功能。
一.索引变化通知
首先我们必须在索引发生改变时得到通知,否则一切都无从谈起。幸运的是CocoaTouch为我们提供了这一接口:
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int{
}
当用户在索引上下搓揉时,以上方法会被调用,其中包含选中索引的标题和index等信息。
二.创建索引放大器
知道索引何时改变,接下来要创建一个视图来显示放大后的索引,在控制器中添加一个实例变量:
///显示索引放大标题的Label
private var indexBigLbl:UILabel!
然后创建一个方法来设置它:
private func setupIndexBigLabel(){
indexBigLbl = UILabel()
indexBigLbl.text = "X"
indexBigLbl.font = UIFont.systemFont(ofSize: 30, weight: .heavy)
indexBigLbl.backgroundColor = .orange
indexBigLbl.layer.cornerRadius = 10.0
indexBigLbl.clipsToBounds = true
indexBigLbl.alpha = 0.7
indexBigLbl.textAlignment = .center
indexBigLbl.alpha = 0.0
view.insertSubview(indexBigLbl, aboveSubview: tableView)
indexBigLbl.snp.makeConstraints {make in
make.center.equalToSuperview()
make.width.equalTo(64)
make.height.equalTo(64)
}
}
其外观可以任意设置,这个无所谓,重要的是将其初始透明度设置为0,这是为后面的动画做准备。
我们只需一步,在索引发生变化时设置放大器的标题,将如下代码放入func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int方法中:
indexBigLbl.text = title
哦了!不过这时你啥也看不到,因为indexBigLbl处于透明状态,我们马上来完善它。
三.没有动画就不好玩了 -_-b
最后我们来添加些动画,没有动画的猫时枯燥的猫…
因为在用户滚动索引时会频繁切换索引标题,所以这里对动画有一个要求:就是可以随时停止!
所以这里我们不用UIView动画(不方便),也不用CALayer动画(大题小做),而是用UIViewPropertyAnimator动画来完成,刚刚好。
打开tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int方法,在其中添加如下代码:
//如果之前动画未完成则停止
if fadeInAnim != nil,fadeInAnim!.state == .active{
fadeInAnim?.stopAnimation(true)
fadeInAnim = nil
}
fadeInAnim = UIViewPropertyAnimator(duration: 0.5, curve: .easeOut)
fadeInAnim?.addAnimations({[unowned self] in
self.indexBigLbl.text = title
self.indexBigLbl.alpha = 0.7
},delayFactor:0.0)
//动画完成时将透明度复位
fadeInAnim?.addCompletion {[unowned self] position in
self.indexBigLbl.alpha = 0.0
}
//手动开启动画
fadeInAnim?.startAnimation()
因为有注释,代码也很简单,所以就不再解释。下面是实际效果:
总结
通过这两篇博文,本猫引领大家循序渐进完善了iOS系统列表视图的索引外观调整,学习了如何调用无文档和有文档的接口。希望大家可以有所收获,感谢观赏 ;)