在做iOS 开发的最常用到的就是tableview,因此最常见的也就是tableview 的重用问题,这次我来介绍一种tableview 的重用的场景 和如何解决这个重用的问题。首先来看一个图片
1C1B4EAB-491F-47E1-9F64-88A13FC7B270.png这是一个播放的音乐的界面,这里可能会涉及到两个明显的问题,(1)一个播放进度条的进度渲染,需要用到定时器去不断的渲染红点的位置,那么需要用到多少个定时器,应该怎么优化呢,(2)第二个就是在滚动tableview 由于cell 重用的影响会导致没有被点击的播放的cell,红点的位置,播放时间 ,还有播放按钮的状态错误。
(1)第一个问题和我之前写的一篇文章的思路很类似http://www.jianshu.com/p/9784a996d187
大概的思路一个定时器去刷新可见cell 的ui ,由于这个场景是只用对一个cell 操作,那么可以记录下这个正在播放的cell 的索引,通过判断这个cell 是否为空,来判断他是否可见,可以看这个代码段
if let cell : ReAudioListTableViewCell = tableView1.cellForRowAtIndexPath(curIndex) as? ReAudioListTableViewCell
{
}
那么只需在if里面刷新 cell的ui 即可
(2)第二个问题,由于我们只是处理可见cell 的话,那么在滚动的时候还是会导致其中的一个cell 的由于重用的问题,导致他的进度条的状态和音乐播放时间的状态的错乱,
1 导致错误的原因也很简单,先看下,下面的图片
1515D109-B807-4804-B3E2-F805003828DB.png
由于cell 的重用数组是用从不可见cell获取的,那么可见cell刚好获取正在播放的cell,那么状态就变了。
2要怎么防止重用状态错乱
每次滚动tableview都会调用cellforindexpath,只要我们把每个cell的状态通过这个代理方法告诉tableiview 即可。
3 那么用什么来标记cell的状态,
我现在使用 了curIndex,来记录当前选中的cell 的索引,isplay记录当前选中的cell是否在播放,
大致的思路介绍完了来看下代码
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! ReAudioListTableViewCell
//记录下来判断是否为可见cell
cell.tag = indexPath.row
//加载本地音乐
let path:String = NSBundle.mainBundle().pathForResource("lj", ofType:"mp3")!
let dict = ["path" : path , "time":"64.0" , "size":"1.8" ,"second":"64.0"]
cell.getAudioDict(dict)
cell.title.text = "录音" + String(indexPath.row+1) + ".aac"
if isfirst
{
//第一次加载默认不播放状态
cell.noPlay()
}
else
{
//当前点击的索引
if indexPath.row == curIndex.row
{
//如果播放设置为播放的状态
if isPlay == true
{
//记录播放的状态和进度
cell.playBtn.selected = true
cell.playBar.playProgress(CGFloat(playProgress))
}
//如果没有播放显示未播放状态
else
{
cell.noPlay()
}
}
//不是当前点击说明没有播放
else{
cell.noPlay()
}
}
return cell
}
最后再说说一种场景就是,(1)选择当前的播放的cell,在点一次就需要关闭,(2)或者选择另外一个cell,要暂停前一个,播放当前的这个,思路又是怎样的呢(还是利用的报存当前的索引curIndex)
1 判断curIndex 和 didselect 的index 是否相同,相同的播放 在通过isplay 判断是否正在播放,播放则暂停,暂停则继续播放
2 如果curIndex 和 didselect 的index 不相同,说明是场景2 ,则需要修改判断前一个cell是否在播放,播放则需修改上次状态为暂停,这里需要注意两个点,来看下代码段
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! ReAudioListTableViewCell
//如果首次播放 curIndex 没有赋值 ,需要特殊处理一下
if isfirst
{
//记录当前选中索引
//已非第一次选中
isfirst = false
//运行定时器
timeTick = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "playingAction", userInfo: nil, repeats: true)
// NSRunLoop.currentRunLoop().addTimer(timeTick, forMode: NSRunLoopCommonModes)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
cell.startPlay()
//////////////////////////////////注意
////////////curIndex = indexPath 需要写在timeTick.fire() 之前,因为fire() 会让定时器先跑完一次方法,才会执行下面的代码,由于这个curIndex 赋值在定时器方法用到,所以需要先赋值,如果想改变可以将定时器放入队列中
curIndex = indexPath
timeTick.fire()
}
else
{
//如果上次选中和当前选中索引相同,说明用户再次点击正在播放的cell,希望音乐暂停
if(curIndex.row == indexPath.row)
{
//如果正在播放
if isPlay == true
{
isPlay = false
cell.stopPlay()
timeTick.invalidate()
}
else
{
cell.startPlay()
isPlay = true
timeTick = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "playingAction", userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timeTick, forMode: NSRunLoopCommonModes)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
cell.playBtn.selected = true
timeTick.fire()
curIndex = indexPath
}
}
//点击一个新的cell播放
else
{
//////////////////////////////////注意
////////////需要判断lastcell 是否为空,如果lastcell 不可见可能会为空
if let lastcell : ReAudioListTableViewCell = tableView1.cellForRowAtIndexPath(curIndex) as? ReAudioListTableViewCell {
lastcell.stopPlay()
}
if RecorderTool.getTool().player.playing {
RecorderTool.getTool().player.stop()
}
//当前cell 开始播放
cell.startPlay()
isPlay = true
//设置定时器
timeTick = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "playingAction", userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timeTick, forMode: NSRunLoopCommonModes)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
curIndex = indexPath
timeTick.fire()
}
}
}
demo 的链接如下 ,如果有说的不对地方,各位大神多多指教
https://github.com/heysunnyboy/audioList.git
网友评论