网易云音乐
- 启动页
- 发现
- 定时器控制轮播图
- UIButtonConfiguration
- 发现
- 换头像
- 我的
- 总结
启动页
这里我的启动页是使用Xcode自带的启动功能,将图片放置在LaunchScreen中即可。这里也可以通过定时器控制,来实现启动的效果
效果图:
这里放一篇大佬的博客,讲的比较详细:
Xcode 中设置APP的图标(Icon)和启动页面(Launch Screen)
发现
这里先给出效果图:
定时器控制轮播图
这里实现定时器控制时要注意,在滚动屏幕时定时器应该停止工作,不然在滚动停止时,由于定时器工作,可能会立刻跳转图片;在动图中看到在我滑动滚动视图以外区域时,定时器并没有停止工作,这个效果使用下面这个代码实现:
**这样设置定时器是将定时器添加到了主runloop中,这样就可以确保定时器在各种交互场景下都可以正常运行。
代码实现:
-(void) beginTime
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(press:) userInfo:nil repeats:YES];
}
-(void) stopTime
{
[self.timer invalidate];
self.timer = nil;
}
-(void) press: (MyCell*) cell
{
NSInteger pageX = self.scrollview.contentOffset.x / ([UIScreen mainScreen].bounds.size.width - 40 );
self.Page.currentPage = pageX - 1;
if (pageX == 3) {
[self.scrollview setContentOffset:CGPointMake(0, 0) animated:NO];
[self.scrollview setContentOffset:CGPointMake(([UIScreen mainScreen].bounds.size.width - 40), 0) animated:YES];
pageX = 1;
} else {
[self.scrollview setContentOffset:CGPointMake(([UIScreen mainScreen].bounds.size.width - 40) * (pageX + 1), 0) animated:YES];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self stopTime];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[self beginTime];
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
无限轮播图的实现与ZARA中相同,这里就不做讲解了
UIButtonConfiguration
UIButtonConfiguration 是 iOS 15 及以后版本中新引入的一个用于配置 UIButton 外观的类。它提供了一种更加灵活和结构化的方式来定义按钮的样式和行为。 在iOS15.0之后无法直接在按钮中同时添加图片文字并且调整位置了,所以我们需要借助UIButtonConfiguration实现,在我的效果图中,推荐歌单就是借助这个实现了。
下面通过一个使用的代码进行讲解:
NSArray* arr = [NSArray arrayWithObjects:@"每日推荐",@"歌单",@"排行榜",@"电台",@"直播",@"有声书", @"歌手",@"专辑",nil];
for(int i = 0; i < 8; i++) {
NSString *str = arr[i];
NSString *strImage = [NSString stringWithFormat:@"%@.png",str];
UIButtonConfiguration *config = [UIButtonConfiguration plainButtonConfiguration];//创建一个UIButtonConfiguration对象
config.attributedTitle = [[NSAttributedString alloc] initWithString:str];//设置按钮的富文本标题
config.image = [UIImage imageNamed:strImage];//甚至按钮的图片
//设置图片与文字的位置
config.imagePlacement = NSDirectionalRectEdgeTop;
config.buttonSize = UIButtonConfigurationSizeMini;
config.imagePadding = 8;
config.baseForegroundColor = [UIColor blackColor];
//将这个添加到一个按钮中去
UIButton* btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.configuration = config;
btn.frame = CGRectMake(i * 100, 0, 100, 100);
//在滚动视图中加入btn这个按钮
[self.scrollview addSubview:btn];
}
发现
这里先给出我的效果图
这个界面中,主要需要实现的是照片墙中更换图片,导航栏中添加按钮事件,其余的在前面都进行过讲解,自定义cell中使用UIButtonConfigurtion,添加含有文字图片的按钮,使用分栏控件控制滚动视图。
换头像
这里换头像我使用的是协议传值,后面我也会将五大传值单独写一篇博客进行总结讲解五大传值。
if(self.selectedCount == 0) {
self.elertView = [UIAlertController alertControllerWithTitle:@"警告" message:@"请选择一张图片更换" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* action = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){}];
[self.elertView addAction:action];
[self presentViewController:self.elertView animated:YES completion:nil];
} else if (self.selectedCount == 1) {
for(UIView* subview in self.scrollview.subviews) {
if([subview isKindOfClass:[UIButton class]]) {
UIButton* button = (UIButton*) subview;
if(button.selected) {
UIImage* image = [button imageForState:UIControlStateNormal];
[self.delegate ChangePhoto:image];
button.selected = NO;
[self.navigationController popViewControllerAnimated:YES];
break;
}
}
}
} else {
self.elertView = [UIAlertController alertControllerWithTitle:@"警告" message:@"禁止一次选用多张图片更换" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* action = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){}];
[self.elertView addAction: action];
[self presentViewController:self.elertView animated:YES completion:nil];
}
这段代码是我对图片被选中多少的判断,可以在警告对话框事件函数中将选中按钮恢复,这样会更合理一点。
这两行代码用于设置是否被选中图片
我的
这个界面最主要的就是夜间模式,这里重点讲解夜间模式,先放上效果图可以看一看。
这里夜间模式传递到其他的页面是我使用的通知传值,后面在进行讲解如何实现通知传值,这里先不做讲解。
先在自定义cell控件使用时添加事件函数,而后通过一个全局开关的属性来控制其他cell的颜色,并用来通知传值。
-(void) pressSwitch: (UISwitch*) sw
{
self.switchon = sw.isOn;
BOOL A = self.switchon;
//通知传值
NSDictionary* dict = @{@"switch":@(A)};
[[NSNotificationCenter defaultCenter] postNotificationName:@"string" object:nil userInfo:dict];
if(self.switchon) {
[self.tableView reloadData];
self.tableView.backgroundColor = [UIColor blackColor];
self.tabBarController.tabBar.backgroundColor = [UIColor darkGrayColor];
self.tabBarController.tabBar.barTintColor = [UIColor darkGrayColor];
self.tabBarController.tabBar.tintColor = [UIColor grayColor];
} else {
UIColor* wechat = [UIColor colorWithRed:(CGFloat)0xF7/255.0 green:(CGFloat)0xF7/255.0 blue:(CGFloat)0xF7/255.0 alpha:1.0];
self.tableView.backgroundColor = wechat;
self.tabBarController.tabBar.backgroundColor = wechat;
self.tabBarController.tabBar.barTintColor = wechat;
self.tabBarController.tabBar.tintColor = [UIColor grayColor];
[self.tableView reloadData];
}
}
**注意:通知传值到其他页面,如果没有打开过第二个页面,第二个页面就不会加载,这样他就无法接收到通知传值的信息,所以我们需要开始时将三个页面全部加载,这里给出代码:
在自定义cell使用时,会发现第一个cell和导航栏可能存在一定的间隙,可以使用这个函数解决
总结
网易云音乐仿写过程中,运用了许多之前学习的内容对老知识进行了巩固 ,也学习了新的知识,在学习传值时比较花时间,在后面的3g share、管理系统中都有着大量的应用。