UICollectionView 子控件按钮切换背景图遇到的问题
一,初始化自定义cell
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {//创建按钮,
self.voiceButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *voiceImage = [UIImage imageNamed:@"语音"];
[self.voiceButton setBackgroundImage:voiceImage forState:UIControlStateNormal];
[self.voiceButton addTarget:self action:@selector(pressToVoice:) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
二,了解cell的加载机制
UICollectionViewCell 通过初始化的时候,UICollectionViewCell 初始化的时候会给每一个cell 一个唯一的标识。当系统在创建的时候,优先从复用池中取出有相应标识的cell 进行复用。如果取出的cell 没有相对于的标识。会自动创建并分配相应的标识,以至于节约系统内存,防止重复创建以浪费系统资源和内存。
当然这是在UICollectionViewCell 创建尺寸是整个屏幕大小的时候,所以在这样的情况下在初始化的时候系统优先初始化用户点击进去的第一个(不一定是第0个 有可能是用户点击中间位置进去的那个第一次响应的cell)这是UICollectionViewCell 初始化的机制。
三,当滚动的时候加载和刷新机制
当用户手动拖动cell 的时候,UICollectionViewCell 会来回的复用相应的标识,因为这是最基本的控件加载机制。如果这时候监听按钮发音完切换图片的时候,如下代码。
播放完语音的时候自动切换,对相应的cell中的按钮控件进行状态的改变
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{//默认的图片是语音,播放完过后改变背景图为语音1
[_showDetailCell.voiceButton setBackgroundImage:[UIImage imageNamed:@"语音1"] forState:UIControlStateNormal];
}
这时你会发现按钮好像根本不好使,明明很简单的东西为什么就不好用呢,仔细的推敲一下,断点调试过后你才知道原来是UICollectionViewCell 的加载机制原理根本不是我们想的那样,所以这是问题的关键,UICollectionViewCell 在cell的尺寸正好是屏幕大小的时候你会发现当你拖动每一个cell的时候,UICollectionView会进行相应的预加载,当你拖动当前的cell的时候UICollectionViewCell 会进行预加载下一个cell,所以当你去取当前按钮让它切换背景的时候,其实当前的按钮根本不会改变,或者出先错乱。所以这里就是最大的问题。
拖动第二个的时候预加载第三个,拖动第三个的时候预加载第四个,往前这相反,拖动第三个的是预加载第一个。所以我们往往会第一时间想法在初始化UICollectionViewCell 的时候取出当前的cell。但是UICollectionViewCell 创建的cell 是屏幕的尺寸的时候,其实UICollectionViewCell 只会初始化两次。所以在初始化方法中赋值全局的cell时候肯定就不是我们要的对象。
四,正确取出对象
以上问题经过不断的去努力查阅资料,终于解决了这个问题。UICollectionViewCell
在滚动的时候去取出想要的对应的cell,在播放语音的时候切换图片,播放完任然按照上边的方法走,只要取出的cell 对象没错。就完美解决了
首先取出相对于的indexPath的cell
NSIndexPath *currentIndexPath = [NSIndexPath indexPathForRow:_currentIndex inSection:0];
self.showDetailCell = (ShowDetailEnemyCollectionViewCell *)[self.collecttion cellForItemAtIndexPath:currentIndexPath];
当播放语音的时候让他显示发音的图片
[_player play];
[self.showDetailCell.voiceButton setBackgroundImage:[UIImage imageNamed:@"语音"] forState:UIControlStateNormal];
执行者一系列的操作过后,再根据发音代理方法执行发音结束,此问题就完美解决了,以后的问题都是小问题,只有自己想不到的,没有自己做不到的,所以以后凡事多思考,从各个方面思考问题,多查阅资料。一定可以克服任何问题。。。。