Swfit - 使用自定义的UIRefreshControl下拉刷新界面
默认 UIRefreshControl 下拉刷新界面是一个菊花进度条+一段描述文字,略显单调。其实我们可以使用自己创建的界面视图,方便我们实现各种效果。比如添加个动态图片,添加个动画效果什么的。
1,下面演示如何使用自定义的下拉刷新界面,效果图如下:
(1)随着下拉,界面透明度从0开始慢慢显示出来
(2)开始刷新时,文字会有跑马灯效果(字体逐个变大,同时会变色)
2,首先使用xib创建一个界面(RefreshView.xib)
(1)其属性做如下设置
(2)在里面添加6个Label,用来显示描述文字(由于文字要单独播放动画,所以要分开)
(3)分别给各个Label添加约束
我习惯先给中间一个定好位,其它的文本标签根据中间的来排。由于是6个Label,那就先设置第3个Label(“刷”)的约束,宽高固定,垂直居中,水平-19居中。
设置第2个Label(“拉”)约束,宽高固定,水平距右10,垂直居中
其它标签依次类推(间距都是10)
3,主页代码
(1)为更好的看到效果,模拟网络请求,这里使用NSTimer延时3秒生成数据
(2)一定要把 UIRefreshControl 的 backgroundColor 和 tintColor 设置成 UIColor.clearColor()。否则自定义的刷新界面高度不会自动拉伸,会变成固定高度的。
import UIKit class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { //新闻列表 @IBOutlet weak var newsTableView: UITableView! //新闻数组集合 var dataArray:[HanggeArticle] = [HanggeArticle]() //拉刷新控制器 var refreshControl = UIRefreshControl() var customView: UIView! var labelsArray: Array<UILabel> = [] var currentColorIndex = 0 var currentLabelIndex = 0 var timer: NSTimer! override func viewDidLoad() { super.viewDidLoad() //添加刷新 refreshControl.addTarget(self, action: "refreshData", forControlEvents: UIControlEvents.ValueChanged) //背景色和tint颜色都要清除,保证自定义下拉视图高度自适应 refreshControl.backgroundColor = UIColor.clearColor() refreshControl.tintColor = UIColor.clearColor() newsTableView.addSubview(refreshControl) loadData() //加载自定义刷新界面 loadCustomRefreshView() } //自定义刷新界面 func loadCustomRefreshView() { let refreshContents = NSBundle.mainBundle().loadNibNamed("RefreshView", owner: self, options: nil) customView = refreshContents[0] as! UIView customView.frame = refreshControl.bounds customView.alpha = 0.0 for var i=0; i<customView.subviews.count; ++i { labelsArray.append(customView.viewWithTag(i + 1) as! UILabel) } refreshControl.addSubview(customView) } //滚动视图开始拖动 func scrollViewWillBeginDragging(scrollView: UIScrollView) { if !refreshControl.refreshing { self.labelsArray[0].text = "下" self.labelsArray[1].text = "拉" self.labelsArray[2].text = "刷" self.labelsArray[3].text = "新" self.labelsArray[4].text = "数" self.labelsArray[5].text = "据" } } //视图拖动 func scrollViewDidScroll(scrollView: UIScrollView) { //加载界面透明度改变 let sg = ( scrollView.contentOffset.y * -1 ) / 60.0 customView.alpha = sg } // 刷新数据 func refreshData() { self.labelsArray[0].text = "数" self.labelsArray[1].text = "据" self.labelsArray[2].text = "加" self.labelsArray[3].text = "载" self.labelsArray[4].text = "中" self.labelsArray[5].text = "..." //播放动画 playAnimateRefresh() //模拟加载数据 timer = NSTimer.scheduledTimerWithTimeInterval(3.0, target: self, selector: "loadData", userInfo: nil, repeats: true) } //播放文字动画 func playAnimateRefresh() { //文字放大,变色动画 UIView.animateWithDuration(0.15, delay: 0.0, options: .CurveLinear, animations: { () -> Void in self.labelsArray[self.currentLabelIndex].transform = CGAffineTransformMakeScale(1.5, 1.5) self.labelsArray[self.currentLabelIndex].textColor = self.getNextColor() }, completion: { (finished) -> Void in //文字样式还原动画 UIView.animateWithDuration(0.1, delay: 0.0, options: .CurveLinear, animations: { () -> Void in self.labelsArray[self.currentLabelIndex].transform = CGAffineTransformIdentity self.labelsArray[self.currentLabelIndex].textColor = UIColor.blackColor() }, completion: { (finished) -> Void in ++self.currentLabelIndex if self.currentLabelIndex == self.labelsArray.count - 1 { self.currentLabelIndex = 0 } //没加载完则继续播放动画 if self.refreshControl.refreshing { self.playAnimateRefresh() }else{ self.currentLabelIndex = 0 } }) }) } //计时器时间到,加载数据 func loadData() { //移除老数据 self.dataArray.removeAll() //随机添加5条新数据(时间是当前时间) for _ in 0..<5 { let atricle = HanggeArticle(title: "新闻标题\(Int(arc4random()%1000))", createDate: NSDate()) self.dataArray.append(atricle) } self.newsTableView.reloadData() self.refreshControl.endRefreshing() timer?.invalidate() timer = nil } // 返回记录数 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dataArray.count; } // 返回单元格内容 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "myCell") //设置单元格标题 let atricle: HanggeArticle = dataArray[indexPath.row] as HanggeArticle cell.textLabel?.text = atricle.title //设置单元格副标题 let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" let str = dateFormatter.stringFromDate(atricle.createDate) cell.detailTextLabel?.text = str return cell; } //获取下一个颜色 func getNextColor() -> UIColor { var colorsArray: Array<UIColor> = [UIColor.magentaColor(), UIColor.brownColor(), UIColor.yellowColor(), UIColor.redColor(), UIColor.greenColor(), UIColor.blueColor(), UIColor.orangeColor()] if currentColorIndex == colorsArray.count { currentColorIndex = 0 } let returnColor = colorsArray[currentColorIndex] ++currentColorIndex return returnColor } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } //新闻结构体 struct HanggeArticle { var title:String var createDate:NSDate }
4,源码下载:hangge_936.zip
博主你好,
refreshControl.addTarget(self, action: "refreshData", forControlEvents: .ValueChanged)
这个绑定的方法是valueChange,现在是向下拉一段距离后就会触发更新,我想实现松开手才进行更新,但是我在绑定方法里面进行了参数修改,尝试无果,望指导
航哥,上拉加载更多怎样做的,个人比较菜,望指导....
你demo中的文字动画,可以用CA动画替换么?需要注意什么???
我按照你的方法,设置了刷新动画customView.frame = refreshControl.bounds;
但是动画宽度,高度固定为320,60,refreshControl.bounds赋给自定义动画钱也是320,60为什么?