韶关网站推广,网页设计与制作学校,自动刷网站关键字排行,网站建设种类 优帮云一、图片处理 说明#xff1a; Aspect表示按照原来的宽高比进行缩放。 Aspectfit表示按照原来的宽高比缩放#xff0c;要求看到全部图片#xff0c;后果是不能完全覆盖窗口#xff0c;会留有空白。 Aspectfill表示按照原来的宽高比缩放#xff0c;但只能看到部分图片。引发… 一、图片处理 说明 Aspect表示按照原来的宽高比进行缩放。 Aspectfit表示按照原来的宽高比缩放要求看到全部图片后果是不能完全覆盖窗口会留有空白。 Aspectfill表示按照原来的宽高比缩放但只能看到部分图片。引发的问题可能会有一部分超出屏幕。 所以如果选择了Aspectfill模式那么需要剪切超出的图片在storyboard中也可以进行设置。 下面的两种设置是等效的。 1在storyboard中进行设置 2使用代码裁剪 二、播放处理 1.当前歌曲播放结束之后继续播放后面的歌曲 解决方案成为播放器的代理。监听播放器的播放。 2.播放中断处理 1 #pragma mark-音乐播放器的代理2 //播放器播放完毕后就会调用该方法 3 -(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag4 {5 [self next];6 }7 //当播放器遇到中断的时候如来电调用该方法 8 -(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player9 {
10 if (self.player.isPlaying) {
11 //如果当前正在播放那么就暂停 12 [self playOrPause];
13 }
14 }
15 //中断事件结束后调用下面的方法 16 -(void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags
17 {
18 //可以什么都不做让用户决定是继续播放还是暂停 19 } 3.开启后台任务 说明新的问题——当播放任务进入到后台运行的时候音乐的播放会停止。 解决方案 YYAppDelegate.m文件中的代码处理如下 争取更多的机会 告诉其是一个音乐播放任务 4.最好是在音频播放工具类中也进行处理。 1 #import YYAudioTool.h 2 3 implementation YYAudioTool4 (void)initialize5 {6 //音频会话 7 AVAudioSession *session [AVAudioSession sharedInstance];8 //设置绘画类型播放类型播放模式会自动停止其他音乐的播放 9 [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
10 //激活会话 11 [session setActive:YES error:nil];
12 }
13 //....... 三、创建歌词控件 创建歌词控件 歌词的格式说明 播放效果 毛玻璃效果的实现 1让美工提供一张半透明的图片 2利用一大堆的图形算法生成毛玻璃样式的UIImage对象 这里使用一个第三方框架来生成毛玻璃效果 毛玻璃英文blur 第三方框架DRNRealTimeBlur 具体实现 新建一个类让其继承自就能够实现毛玻璃效果。 在xib中添加一个歌词控件。 注意歌词控件的层级关系退出和词图两个按钮应该在歌词控件的上面这样才能够点击切换。 把该控件和新建的类进行关联。 添加约束并清空其背景颜色。默认不显示设置隐藏 毛玻璃效果如下 简单的代码处理如下 YYLrcView.m文件 1 // 2 // YYLrcView.m3 // 24-音频处理音乐播放器54 // 5 // Created by apple on 14-8-15.6 // Copyright (c) 2014年 yangyong. All rights reserved.7 //8 9 #import YYLrcView.h 10 11 interface YYLrcView ()UITableViewDataSource,UITableViewDelegate
12 property(nonatomic,strong)UITableView *tableView;
13 end 14 implementation YYLrcView
15 16 - (id)initWithFrame:(CGRect)frame
17 {
18 self [super initWithFrame:frame];
19 if (self) {
20 [self setup];
21 }
22 return self;
23 }
24 25 -(id)initWithCoder:(NSCoder *)aDecoder
26 {
27 self[super initWithCoder:aDecoder];
28 if (self) {
29 [self setup];
30 }
31 return self;
32 }
33 34 -(void)setup
35 {
36 //添加表格控件 37 UITableView *tableView[[UITableView alloc]init];
38 tableView.delegateself;
39 tableView.dataSourceself;
40 [self addSubview:tableView];
41 self.tableViewtableView;
42 }
43 44 #pragma mark-公共方法
45 -(void)setLrcname:(NSString *)lrcname
46 {
47 _lrcname[lrcname copy];
48 }
49 50 #pragma mark-数据源方法
51 #warning TODO
52 53 end 代码说明 注意不要认为只有控制器才能作为tableView的数据源和代理。这也就是为什么代理和数据源属性的类型为id的原因遵守其协议即可做其代理和数据源。 -(id)initWithCoder:。从文件中读取一个对象的时候调用为了程序的严谨性建议在两个方法中调用初始化的代码。 调用这个方法说明对象是从文件中解析出来的。 如果是通过代码alloc\init创建的对象那么调用-(id)initWithFrame:方法。 说明xib文件的本质是xml文件。 四、主控制器的代码补充 YYPlayingViewController.m文件 1 // 2 // YYPlayingViewController.m3 //4 5 #import YYPlayingViewController.h 6 #import YYMusicTool.h 7 #import YYMusicModel.h 8 #import YYAudioTool.h 9 #import YYLrcView.h 10 11 interface YYPlayingViewController ()AVAudioPlayerDelegate12 - (IBAction)lyricOrPic:(UIButton *)sender;13 property (weak, nonatomic) IBOutlet YYLrcView *lrcView;14 //显示拖拽进度 15 property (weak, nonatomic) IBOutlet UIButton *currentTimeView;16 //进度条 17 property (weak, nonatomic) IBOutlet UIView *progressView;18 //滑块 19 property (weak, nonatomic) IBOutlet UIButton *slider;20 property (weak, nonatomic) IBOutlet UIImageView *iconView;21 property (weak, nonatomic) IBOutlet UILabel *songLabel;22 property (weak, nonatomic) IBOutlet UILabel *singerLabel;23 //当前播放的音乐的时长 24 property (weak, nonatomic) IBOutlet UILabel *durationLabel;25 //正在播放的音乐 26 property(nonatomic,strong)YYMusicModel *playingMusic;27 //音乐播放器对象 28 property(nonatomic,strong)AVAudioPlayer *player;29 //定时器 30 property(nonatomic,strong)NSTimer *CurrentTimeTimer;31 - (IBAction)exit;32 - (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender;33 - (IBAction)panSlider:(UIPanGestureRecognizer *)sender;34 - (IBAction)previous;35 - (IBAction)playOrPause;36 - (IBAction)next;37 property (weak, nonatomic) IBOutlet UIButton *playOrPauseButton;38 39 end 40 41 implementation YYPlayingViewController42 43 -(void)viewDidLoad44 {45 [super viewDidLoad];46 47 //裁剪圆角 48 self.currentTimeView.layer.cornerRadius8;49 50 }51 #pragma mark-公共方法52 -(void)show53 {54 //1.禁用整个app的点击事件 55 UIWindow *window[UIApplication sharedApplication].keyWindow;56 window.userInteractionEnabledNO;57 58 //2.添加播放界面59 //设置View的大小为覆盖整个窗口 60 self.view.framewindow.bounds;61 //设置view显示 62 self.view.hiddenNO;63 //把View添加到窗口上 64 [window addSubview:self.view];65 66 //3.检测是否换了歌曲 67 if (self.playingMusic![YYMusicTool playingMusic]) {68 [self resetPlayingMusic];69 }70 71 //4.使用动画让View显示 72 self.view.yself.view.height;73 [UIView animateWithDuration:0.25 animations:^{74 self.view.y0;75 } completion:^(BOOL finished) {76 77 //设置音乐数据 78 [self starPlayingMusic];79 window.userInteractionEnabledYES;80 }];81 }82 83 84 #pragma mark-私有方法85 //重置正在播放的音乐 86 -(void)resetPlayingMusic87 {88 //1.重置界面数据 89 self.iconView.image[UIImage imageNamed:play_cover_pic_bg];90 self.songLabel.textnil;91 self.singerLabel.textnil;92 93 //2.停止播放 94 [YYAudioTool stopMusic:self.playingMusic.filename];95 //把播放器进行清空 96 self.playernil;97 98 //3.停止定时器 99 [self removeCurrentTime];
100 101 //4.设置音乐播放按钮的状态 102 self.playOrPauseButton.selectedNO;
103 }
104 //开始播放音乐数据 105 -(void)starPlayingMusic
106 {
107 //1.设置界面数据
108 109 //如果当前播放的音乐就是传入的音乐那么就直接返回 110 if (self.playingMusic[YYMusicTool playingMusic])
111 {
112 //把定时器加进去 113 [self addCurrentTimeTimer];
114 return;
115 }
116 //存取音乐 117 self.playingMusic[YYMusicTool playingMusic];
118 self.iconView.image[UIImage imageNamed:self.playingMusic.icon];
119 self.songLabel.textself.playingMusic.name;
120 self.singerLabel.textself.playingMusic.singer;
121 122 //2.开始播放 123 self.player [YYAudioTool playMusic:self.playingMusic.filename];
124 self.player.delegateself;
125 126 //3.设置时长
127 //self.player.duration; 播放器正在播放的音乐文件的时间长度 128 self.durationLabel.text[self strWithTime:self.player.duration];
129 130 //4.添加定时器 131 [self addCurrentTimeTimer];
132 133 //5.设置音乐播放按钮的状态 134 self.playOrPauseButton.selectedYES;
135 136 //6.设置歌词 137 self.lrcView.lrcnameself.playingMusic.lrcname;
138 }
139 140 /**
141 *把时间长度--时间字符串
142 */ 143 -(NSString *)strWithTime:(NSTimeInterval)time
144 {
145 int minutetime / 60;
146 int second(int)time % 60;
147 return [NSString stringWithFormat:%d:%d,minute,second];
148 }
149 150 #pragma mark-定时器控制
151 /**
152 * 添加一个定时器
153 */ 154 -(void)addCurrentTimeTimer
155 {
156 //如果当前没有在播放那么就直接返回 157 if (self.player.isPlayingNO) return;
158 159 //在添加一个定时器之前先把以前的定时器移除 160 [self removeCurrentTime];
161 162 //提前先调用一次进度更新以保证定时器的工作时及时的 163 [self updateCurrentTime];
164 165 //创建一个定时器每一秒钟调用一次 166 self.CurrentTimeTimer[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:selector(updateCurrentTime) userInfo:nil repeats:YES];
167 //把定时器加入到运行时中 168 [[NSRunLoop mainRunLoop]addTimer:self.CurrentTimeTimer forMode:NSRunLoopCommonModes];
169 }
170 /**
171 *移除一个定时器
172 */ 173 -(void)removeCurrentTime
174 {
175 [self.CurrentTimeTimer invalidate];
176 177 //把定时器清空 178 self.CurrentTimeTimernil;
179 }
180 181 /**
182 * 更新播放进度
183 */ 184 -(void)updateCurrentTime
185 {
186 //1.计算进度值 187 double progressself.player.currentTime/self.player.duration;
188 189 //2.计算滑块的x值
190 // 滑块的最大的x值 191 CGFloat sliderMaxXself.view.width-self.slider.width;
192 self.slider.xsliderMaxX*progress;
193 //设置滑块上的当前播放时间 194 [self.slider setTitle:[self strWithTime:self.player.currentTime] forState:UIControlStateNormal];
195 196 //3.设置进度条的宽度 197 self.progressView.widthself.slider.center.x;
198 199 }
200 201 #pragma mark-内部的按钮监听方法
202 //返回按钮 203 - (IBAction)exit {
204 205 //0.移除定时器 206 [self removeCurrentTime];
207 //1.禁用整个app的点击事件 208 UIWindow *window[UIApplication sharedApplication].keyWindow;
209 window.userInteractionEnabledNO;
210 211 //2.动画隐藏View 212 [UIView animateWithDuration:0.25 animations:^{
213 self.view.ywindow.height;
214 } completion:^(BOOL finished) {
215 window.userInteractionEnabledYES;
216 //设置view隐藏能够节省一些性能 217 self.view.hiddenYES;
218 }];
219 220 }
221 222 /**
223 *点击了进度条
224 */ 225 - (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender {
226 //获取当前单击的点 227 CGPoint point[sender locationInView:sender.view];
228 //切换歌曲的当前播放时间 229 self.player.currentTime(point.x/sender.view.width)*self.player.duration;
230 //更新播放进度 231 [self updateCurrentTime];
232 }
233 /**
234 *拖动滑块
235 */ 236 - (IBAction)panSlider:(UIPanGestureRecognizer *)sender {
237 238 //1.获得挪动的距离 239 CGPoint t[sender translationInView:sender.view];
240 //把挪动清零 241 [sender setTranslation:CGPointZero inView:sender.view];
242 243 //2.控制滑块和进度条的frame 244 CGFloat sliderMaxXself.view.width-self.slider.width;
245 self.slider.xt.x;
246 //控制滑块的frame不让其越界 247 if(self.slider.x0)
248 {
249 self.slider.x0;
250 }else if (self.slider.xsliderMaxX)
251 {
252 self.slider.xsliderMaxX;
253 }
254 //设置进度条的宽度 255 self.progressView.widthself.slider.center.x;
256 257 //3.设置时间值 258 double progressself.slider.x/sliderMaxX;
259 //当前的时间值音乐的时长*当前的进度值 260 NSTimeInterval timeself.player.duration*progress;
261 [self.slider setTitle:[self strWithTime:time] forState:UIControlStateNormal];
262 263 //设置拖拽进度的X的值 264 self.currentTimeView.xself.slider.x;
265 [self.currentTimeView setTitle:self.slider.currentTitle forState:UIControlStateNormal];
266 267 //4.如果开始拖动那么就停止定时器 268 if (sender.stateUIGestureRecognizerStateBegan) {
269 //停止定时器 270 [self removeCurrentTime];
271 272 //设置拖拽进度
273 //显示 274 self.currentTimeView.hiddenNO;
275 self.currentTimeView.yself.currentTimeView.superview.height-5-self.currentTimeView.height;
276 277 }else if(sender.stateUIGestureRecognizerStateEnded)
278 {
279 //隐藏 280 self.currentTimeView.hiddenYES;
281 //设置播放器播放的时间 282 self.player.currentTimetime;
283 #warning 如果正在播放才需要添加定时器
284 // if (self.player.isPlaying) {
285 //开启定时器 286 [self addCurrentTimeTimer];
287 // } 288 }
289 }
290 291 //上一首 292 - (IBAction)previous {
293 //1.在开始播放之前禁用一切的app点击事件 294 UIWindow *window[[UIApplication sharedApplication].windows lastObject];
295 window.userInteractionEnabledNO;
296 297 //2.重置当前歌曲 298 [self resetPlayingMusic];
299 300 //3.获得上一首歌曲 301 [YYMusicTool setPlayingMusic:[YYMusicTool previousMusic]];
302 303 //4.播放上一首歌曲 304 [self starPlayingMusic];
305 306 //5.回复window的点击为可用 307 window.userInteractionEnabledYES;
308 }
309 //下一首 310 - (IBAction)next {
311 //1.在开始播放之前禁用一切的app点击事件 312 UIWindow *window[[UIApplication sharedApplication].windows lastObject];
313 window.userInteractionEnabledNO;
314 315 //2.重置当前歌曲 316 [self resetPlayingMusic];
317 318 //3.获得下一首歌曲 319 [YYMusicTool setPlayingMusic:[YYMusicTool nextMusic]];
320 321 //4.播放下一首歌曲 322 [self starPlayingMusic];
323 324 //5.回复window的点击为可用 325 window.userInteractionEnabledYES;
326 }
327 328 //继续或暂停播放 329 - (IBAction)playOrPause {
330 if (self.playOrPauseButton.isSelected) {//暂停 331 self.playOrPauseButton.selectedNO;
332 //暂停播放 333 [YYAudioTool pauseMusic:self.playingMusic.filename];
334 //停掉定时器 335 [self removeCurrentTime];
336 }else 337 {
338 self.playOrPauseButton.selectedYES;
339 //继续播放 340 [YYAudioTool playMusic:self.playingMusic.filename];
341 //开启定时器 342 [self addCurrentTimeTimer];
343 }
344 }
345 346 #pragma mark-音乐播放器的代理
347 //播放器播放完毕后就会调用该方法 348 -(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
349 {
350 [self next];
351 }
352 //当播放器遇到中断的时候如来电调用该方法 353 -(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
354 {
355 if (self.player.isPlaying) {
356 //如果当前正在播放那么就暂停 357 [self playOrPause];
358 }
359 }
360 //中断事件结束后调用下面的方法 361 -(void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags
362 {
363 //可以什么都不做让用户决定是继续播放还是暂停 364 }
365 - (IBAction)lyricOrPic:(UIButton *)sender {
366 if (self.lrcView.hidden) {
367 //显示歌词 368 self.lrcView.hiddenNO;
369 sender.selectedYES;
370 }else 371 {
372 //隐藏歌词显示歌手图片 373 self.lrcView.hiddenYES;
374 sender.selectedNO;
375 }
376 }
377 end