【iOS】APP仿写——网易云音乐
网易云音乐
- 启动页
- 发现
- 定时器控制轮播图
- 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、管理系统中都有着大量的应用。
相关文章:
【iOS】APP仿写——网易云音乐
网易云音乐 启动页发现定时器控制轮播图UIButtonConfiguration 发现换头像 我的总结 启动页 这里我的启动页是使用Xcode自带的启动功能,将图片放置在LaunchScreen中即可。这里也可以通过定时器控制,来实现启动的效果 效果图: 这里放一篇大…...
react 快速入门思维导图
在掌握了react中一下的几个步骤和语法,基本上就可以熟练的使用react了。 1、组件的使用。react创建组件主要是类组件和函数式组件,类组件有生命周期,而函数式组件没有。 2、jsx语法。react主要使用jsx语法,需要使用babel和webpa…...
微软研究人员为电子表格应用开发了专用人工智能LLM
微软的 Copilot 生成式人工智能助手现已成为该公司许多软件应用程序的一部分。其中包括 Excel 电子表格应用程序,用户可以在其中输入文本提示来帮助处理某些选项。微软的一组研究人员一直在研究一种新的人工智能大型语言模型,这种模型是专门为 Excel、Go…...
[算法题]两个链表的第一个公共结点
题目链接: 两个链表的第一个公共结点 图示: 两个链表如果长度一致, 那么两人同时一人走一步, 如果存在公共结点, 迟早会相遇, 但是如果长度不一致单存在公共结点, 两人同时一人走一步不会相遇, 此时定义两个变量, node1 和 node2, 这两个变量分别从 x1 和 x2 开始走, 当其走完…...
MySQL事务管理(上)
目录 前言 CURD不加控制,会有什么问题? CURD满足什么属性,能解决上述问题? 事务 什么是事务? 为什么会出现事务 事务的版本支持 事务提交方式 查看事务提交方式 改变 MySQL 的自动提交模式: 事务常见操作方式 前…...
HTML2048小游戏
源代码在效果图后面 效果图 源代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>2048 Game&l…...
为 android编译 luajit库、 交叉编译
时间:20200719 本机环境:iMac2017 macOS11.4 参考: 官方的文档:Use the NDK with other build systems 写在前边:交叉编译跟普通编译类似,无非是利用特殊的编译器、链接器生成动态或静态库; make 本质上是按照 Make…...
【音视频】音频重采样
文章目录 前言音频重采样的基本概念音频重采样的原因1. 设备兼容性2. 文件大小和带宽3. 音质优化4. 标准化和规范5. 多媒体同步6. 降低处理负载重采样的注意事项 总结 前言 音频重采样是指将音频文件的采样率转换成另一种采样率的过程。这在音频处理和传输中是一个常见且重要的…...
卷积神经网络学习问题总结
问题一: 深度学习中的损失函数和应用场景 回归任务: 均方误差函数(MSE)适用于回归任务,如预测房价、预测股票价格等。 import torch.nn as nn loss_fn nn.MSELoss() 分类任务: 交叉熵损失函数&…...
嵌入式面试总结
C语言中struct和union的区别 struct和union都是常见的复合结构。 结构体和联合体虽然都是由多个不同的数据类型成员组成的,但不同之处在于联合体中所有成员共用一块地址空间,即联合体只存放了一个被选中的成员,结构体中所有成员占用空间是累…...
超简单安装指定版本的clickhouse
超简单安装指定版本的clickhouse 命令执行shell脚本 idea连接 命令执行 参考官网 # 下载脚本 wget https://raw.githubusercontent.com/183461750/doc-record/d988dced891d70b23c153a3bbfecee67902a3757/middleware/data/clickhouse/clickhouse-install.sh # 执行安装脚本(中…...
FlowUs横向对比几款笔记应用的优势所在
FlowUs作为一个本土化的生产力工具,在中国市场的环境下相对于Notion有其独特的优势,尤其是在稳定性和模板适应性方面。 尽管Notion在笔记和生产力工具领域享有极高的声誉,拥有着诸多创新功能和强大的生态系统,但它并不一定适合每…...
收银系统源码-千呼新零售收银视频介绍
千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…...
从Catalog说到拜义父-《分析模式》漫谈11
DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的Preface(前言)有这么一句: This book is thus a catalog, rather than a book to be read from cover to cover. 2004&am…...
Qt判定鼠标是否在该多边形的线条上
要判断鼠标是否在由QPainterPath或一系列QPointF点定义的多边形的线条上,你可以使用以下步骤: 获取鼠标当前位置:在鼠标事件中,使用QMouseEvent的pos()方法获取鼠标的当前位置。 检查点与线段的距离:遍历多边形的每条…...
【笔记:3D航路规划算法】一、随机搜索锚点(python实现,讲解思路)
目录 关键概念3D路径规划算法1. A*算法2. 快速随机锚点1. 初始化:2. 实例化搜索算法:3. 路径生成:4. 绘制图像: 3D路径规划是在三维空间中寻找从起点到终点的最短或最优路径的一种技术。它广泛应用于无人机导航、机器人运动规划、…...
ubuntu如何彻底卸载android studio?
最新版的ubuntu已经使用snap进行软件管理了,我用snap-store安装android studio以后,在安装plugin的时候强制退出后,直接再也进不去了,启动就报错。 先后进行了如下操作依然不行: 1 重装snap-store和android studio都…...
使用Windows Linux 子系统安装 Tensorflow,并使用GPU环境
在Microsoft Store商店安装Ubuntu 20.04 使用 nvidia-smi 命令查看GPU信息,查看支持的CUDA版本,这里最高支持11.7 安装cuda工具集 进入官网:CUDA Toolkit Archive | NVIDIA Developer,现在对应版本,点击 配置平台&…...
C++案例三:猜数字游戏
文章目录 介绍代码说明设置随机种子生成随机数猜测循环完整代码运行效果介绍 猜数字游戏是一个经典的编程练习,通过这个案例可以学习到基本的输入输出、随机数生成、条件判断和循环结构。 代码说明 设置随机种子 std::srand(static_cast<unsigned int>(std::time(nu…...
LNMP架构部署及应用
部署LNMP架构流程 1.安装Nginx(上传软件包,执行脚本) yum -y install pcre-devel zlib-devel gcc gcc useradd -M -s /sbin/nologin nginx tar zxf nginx-1.12.0.tar.gz cd nginx-1.12.0 ./configure --prefix/usr/local/nginx --usernginx…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
