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()。否则自定义的刷新界面高度不会自动拉伸,会变成固定高度的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | 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 } |
博主你好,
refreshControl.addTarget(self, action: "refreshData", forControlEvents: .ValueChanged)
这个绑定的方法是valueChange,现在是向下拉一段距离后就会触发更新,我想实现松开手才进行更新,但是我在绑定方法里面进行了参数修改,尝试无果,望指导
航哥,上拉加载更多怎样做的,个人比较菜,望指导....
你demo中的文字动画,可以用CA动画替换么?需要注意什么???
我按照你的方法,设置了刷新动画customView.frame = refreshControl.bounds;
但是动画宽度,高度固定为320,60,refreshControl.bounds赋给自定义动画钱也是320,60为什么?