【iOS】3GShare仿写

文章目录

  • 【iOS】3GShare仿写
    • 登陆注册界面
    • 主页
    • 搜索
    • 文章
    • 活动
    • 我的
    • 总结

登陆注册界面

这个界面的ui东西不多,主要就是几个输入框及对输入内容的一些判断

登陆界面

//这里设置了一个初始密码并储存到NSUserDefaults中
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];if (![defaults objectForKey: @"UserAccounts"]) {NSDictionary *defaultUser = @{@"a": @"1"};[defaults setObject: defaultUser forKey: @"UserAccounts"];}
self.textFieldUser = [[UITextField alloc] initWithFrame: CGRectMake(70, 320, 250, 46)];self.textFieldUser.placeholder = @"请输入用户名";self.textFieldUser.borderStyle = UITextBorderStyleRoundedRect;self.textFieldUser.leftView = [self createLefticonViewWithImageName: @"账户.png"];self.textFieldUser.leftViewMode = UITextFieldViewModeAlways;self.textFieldcode = [[UITextField alloc] initWithFrame: CGRectMake(70, 390, 250, 46)];self.textFieldcode.placeholder = @"请输入密码";self.textFieldcode.borderStyle = UITextBorderStyleRoundedRect;self.textFieldcode.secureTextEntry = YES;self.textFieldcode.leftView = [self createRighticonViewWithImageName: @"解锁.png"];self.textFieldcode.leftViewMode = UITextFieldViewModeAlways;UIButton *loginBtn = [UIButton buttonWithType: UIButtonTypeSystem];loginBtn.frame = CGRectMake(85, 470, 90, 40);[loginBtn setTitle: @"登陆" forState: UIControlStateNormal];[loginBtn addTarget: self action: @selector(handleLoginBtn) forControlEvents: UIControlEventTouchUpInside];loginBtn.tintColor = [UIColor whiteColor];loginBtn.layer.borderColor = [UIColor whiteColor].CGColor;loginBtn.layer.borderWidth = 1.0;loginBtn.layer.cornerRadius = 8.0;loginBtn.clipsToBounds = YES;[self.view addSubview: loginBtn];
NSString *username = self.textFieldUser.text;NSString *password = self.textFieldcode.text;if (username.length > 15 || password.length > 15) {UIAlertController *alert2 = [UIAlertController alertControllerWithTitle: @"错误" message: @"账号或密码过长" preferredStyle: UIAlertControllerStyleAlert];[alert2 addAction: [UIAlertAction actionWithTitle: @"确定" style: UIAlertActionStyleDefault handler: nil]];[self presentViewController: alert2 animated: YES completion: nil];return;}NSDictionary *userDict = [[NSUserDefaults standardUserDefaults] objectForKey: @"UserAccounts"];NSString *savedPassword = userDict[username];if (savedPassword && [savedPassword isEqualToString: password]) {MainTabBarController *mainTabBar = [[MainTabBarController alloc] init];self.view.window.rootViewController = mainTabBar;} else {UIAlertController *alertright = [UIAlertController alertControllerWithTitle: @"错误" message: @"账号或密码错误" preferredStyle: UIAlertControllerStyleAlert];[alertright addAction: [UIAlertAction actionWithTitle: @"确定" style: UIAlertActionStyleDefault handler: nil]];[self presentViewController: alertright animated: YES completion: nil];return;}

主要是通过UITextField代理方法在确认后判断框中的字符是否符合标准,再用个警告对话框进行提示

注册界面其他的跟登录界面差不多,主要是要用一个协议传值判断后把新的账号密码传入到前面设置的defaultUser中,关于协议传值的内容前面博客中有所写出,不多阐述

主页

主页界面大体由上面的轮播图和下面的自定义单元格组成

请添加图片描述

里面比较有意思的内容就是点击下面第一个单元格时可进入其详情界面,且这里的点赞功能是正常且完善的

请添加图片描述

这里是同时使用了属性传值与协议传值,属性往里传,协议往外传

详情界面的部分代码:

@protocol SendViewControllerDelegate <NSObject>- (void)didUpdateLikeStatus:(BOOL)isLiked likeCount:(NSInteger)likeCount;@end@interface SendViewController : UIViewController@property (nonatomic, copy) NSString *likeCountText;
@property (nonatomic, assign) BOOL isLiked;
@property (nonatomic, weak) id<SendViewControllerDelegate> delegate;
@property (nonatomic, strong) UIButton *like;@property (nonatomic, strong) UILabel *likecount;
@property (nonatomic, strong) UIImageView *looking;
@property (nonatomic, strong) UIImageView *sharing;
@end
self.like = [UIButton buttonWithType:UIButtonTypeCustom];[self.like setImage:[UIImage imageNamed:@"liking.png"] forState:UIControlStateNormal];[self.like addTarget:self action:@selector(toggleLike) forControlEvents:UIControlEventTouchUpInside];self.like.frame = CGRectMake(235, 75, 30, 30);[self.like setImage:[UIImage imageNamed:(self.isLiked ? @"likingred.png" : @"liking.png")] forState:UIControlStateNormal];[scrollView addSubview:self.like];self.likecount = [[UILabel alloc] init];self.likecount.frame = CGRectMake(265, 80, 40, 20);self.likecount.text = self.likeCountText;[scrollView addSubview: self.likecount];scrollView.contentSize = CGSizeMake(self.view.frame.size.width, CGRectGetMaxY(vImage.frame) + 20);
}
- (void)toggleLike {self.isLiked = !self.isLiked;NSInteger currentCount = [self.likecount.text integerValue];if (self.isLiked) {currentCount += 1;[self.like setImage:[UIImage imageNamed:@"likingred.png"] forState:UIControlStateNormal];} else {currentCount -= 1;[self.like setImage:[UIImage imageNamed:@"liking.png"] forState:UIControlStateNormal];}self.likecount.text = [NSString stringWithFormat:@"%ld", (long)currentCount];if ([self.delegate respondsToSelector: @selector(didUpdateLikeStatus:likeCount:)]) {[self.delegate didUpdateLikeStatus: self.isLiked likeCount: currentCount];}
}

搜索

这个界面的内容主要是可以点击的一些按钮,可以识别输入字符跳转的一个界面还有一个上传界面

请添加图片描述

UITextField *searchField = [[UITextField alloc] initWithFrame:CGRectMake(16, 150, self.view.frame.size.width - 32, 36)];searchField.borderStyle = UITextBorderStyleRoundedRect;searchField.placeholder = @"搜索 用户名 作品分类 文章";searchField.clearButtonMode = UITextFieldViewModeWhileEditing;searchField.returnKeyType = UIReturnKeySearch;searchField.delegate = self;UIImageView *leftImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"搜索.png"]];leftImageView.contentMode = UIViewContentModeScaleAspectFit;leftImageView.frame = CGRectMake(0, 0, 20, 20);UIView *leftViewContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 20)];[leftViewContainer addSubview:leftImageView];leftImageView.center = leftViewContainer.center;searchField.leftView = leftViewContainer;searchField.leftViewMode = UITextFieldViewModeAlways;searchField.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];

其实这个界面主要的还是上传界面

请添加图片描述

这个上传界面的图片墙我使用UICollectionView设置的,若点击一张图片则会储存到一个可变数组当中,再次点击即会取消其被包含的状态,最后会把数组中存储的照片数量和选中的第一张图片返回代替放在选择图片上面

 self.view.backgroundColor = [UIColor whiteColor];self.images = @[@"头像1.jpg", @"头像2.jpg", @"头像3.jpg", @"头像4.jpg", @"头像5.jpg", @"头像6.jpg", @"头像7.jpg", @"头像8.jpg", @"头像9.jpg"];self.selectedIndexes = [NSMutableArray array];//设置collectionview的所处的位置UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];layout.itemSize = CGSizeMake(100, 100);layout.minimumLineSpacing = 20;layout.minimumInteritemSpacing = 10;layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];self.collectionView.delegate = self;self.collectionView.dataSource = self;self.collectionView.backgroundColor = [UIColor whiteColor];[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];[self.view addSubview:self.collectionView];
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {NSNumber *indexNumber = @(indexPath.item);if ([self.selectedIndexes containsObject:indexNumber]) {[self.selectedIndexes removeObject:indexNumber];} else {[self.selectedIndexes addObject:indexNumber];}[collectionView reloadItemsAtIndexPaths:@[indexPath]];
}- (void)doneAction {UIImage *selectedImage = nil;if (self.selectedIndexes.count > 0) {NSNumber *firstIndex = self.selectedIndexes.firstObject;selectedImage = [UIImage imageNamed:self.images[firstIndex.integerValue]];}if ([self.delegate respondsToSelector:@selector(didSelectImage: andCount:)]) {[self.delegate didSelectImage:selectedImage andCount:self.selectedIndexes.count];}[self dismissViewControllerAnimated:YES completion:nil];[self.navigationController popViewControllerAnimated:YES];
}

文章

这个界面是一个分栏控件管理的三个视图控制器,每个视图控制器都是一个分别的自定义cell,并且在其底下有一个横向的滚动视图以确保其可以进行左右滑动

请添加图片描述

self.segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"精选文章", @"热门推荐", @"全部文章"]];self.segmentedControl.frame = CGRectMake(0, 100, self.view.bounds.size.width , 40);self.segmentedControl.selectedSegmentIndex = 0;[self.segmentedControl addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged];self.segmentedControl.backgroundColor = [UIColor whiteColor];UIFont *font = [UIFont systemFontOfSize:18];NSDictionary *attributes = @{NSFontAttributeName: font};[self.segmentedControl setTitleTextAttributes:attributes forState:UIControlStateNormal];[self.segmentedControl setTitleTextAttributes:attributes forState:UIControlStateSelected];[self.view addSubview:self.segmentedControl];self.firstVC = [[FirstVC alloc] init];self.secondVC = [[SecondVC alloc] init];self.thirdVC = [[ThirdVC alloc] init];CGFloat yOffset = CGRectGetMaxY(self.segmentedControl.frame);CGFloat scrollHeight = self.view.bounds.size.height - yOffset;self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, yOffset, self.view.bounds.size.width, scrollHeight)];self.scrollView.pagingEnabled = YES;self.scrollView.showsHorizontalScrollIndicator = NO;self.scrollView.delegate = self;self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 3, scrollHeight);[self.view addSubview:self.scrollView];

活动

这个界面非常简单,只是一个简单的三个自定义的单元格

请添加图片描述

我的

这个界面的东西最多也最繁琐,但是总的看来也就这么几个东西:

第一个就是需要跨多个界面进行传值进行保留

请添加图片描述

请添加图片描述

这里使用的是强属性引用来传值的方法,即设置下一个视图控制器为上一个的属性,若不为空则使用上次创建的那个视图来保存之前设置的状态

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {switch (indexPath.row) {case 0: {if (self.setDatavc == nil) {self.setDatavc = [[SetDataViewController alloc] init];[self.navigationController pushViewController: self.setDatavc animated: YES];break;} else {[self.navigationController pushViewController: self.setDatavc animated: YES];break;}}case 1: {ChangeWordVC *vc = [[ChangeWordVC alloc] init];[self.navigationController pushViewController:vc animated:YES];break;}case 2: {if (self.messagesetvc == nil) {self.messagesetvc = [[MessageSetVC alloc] init];[self.navigationController pushViewController: self.messagesetvc animated: YES];break;} else {[self.navigationController pushViewController: self.messagesetvc animated: YES];break;}}case 3: {UIAlertController *alert3 = [UIAlertController alertControllerWithTitle: @"这是一个古老的软件" message: nilpreferredStyle: UIAlertControllerStyleAlert];[alert3 addAction: [UIAlertAction actionWithTitle: @"确定" style: UIAlertActionStyleDefault handler: nil]];[self presentViewController: alert3 animated: YES completion: nil];break;}case 4: {UIAlertController *alert4 = [UIAlertController alertControllerWithTitle: @"已清理缓存" message: nilpreferredStyle: UIAlertControllerStyleAlert];[alert4 addAction: [UIAlertAction actionWithTitle: @"确定" style: UIAlertActionStyleDefault handler: nil]];[self presentViewController: alert4 animated: YES completion: nil];break;}default:break;}[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

第二个就是一个可以对密码进行修改并确认两次密码是否一样的,因不需要影响登陆进来的原始密码,只是对两次输入的密码进行确认就行了,所以没啥东西掠过

第三个就是里面有关一个简单的聊天室的内容

请添加图片描述

即每次发送消息都切换一个发送方,并根据发送方的不同分别进行相应的布局,在前面记得要设置每方气泡的最大宽度

 if (self.inputField.text.length == 0) {return;}static int count = 0;NSString *text = self.inputField.text;NSString *avatar = (count % 2 == 0) ? @"img03.png" : @"img12.png";MessageType type = (count % 2 == 0) ? MessageTypeSent : MessageTypeReceived;NSString *time = [NSString stringWithFormat: @"10:%02d", count];Message *message = [[Message alloc] initWithText:text time:time avatar:avatar type:type];[self.messages addObject:message];[self.tableView reloadData];[self scrollToBottom];self.inputField.text = @"";count++;
}- (void)keyboardWillShow:(NSNotification *)notification {NSDictionary *userInfo = notification.userInfo;CGRect keyboardFrameInWindow = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];CGRect keyboardFrame = [self.view convertRect:keyboardFrameInWindow fromView:nil];CGFloat keyboardHeight = keyboardFrame.size.height;[UIView animateWithDuration:0.25 animations:^{CGRect inputFrame = self.inputField.superview.frame;CGFloat tabBarHeight = self.tabBarController.tabBar.frame.size.height;inputFrame.origin.y = self.view.bounds.size.height - keyboardHeight - inputFrame.size.height + tabBarHeight;self.inputField.superview.frame = inputFrame;CGRect tableFrame = self.tableView.frame;tableFrame.size.height = inputFrame.origin.y;self.tableView.frame = tableFrame;[self scrollToBottom];}];

同时也要有点击键盘时的上抬,这里记得要考虑减去下面导航栏的高度,否则可能会导致那个输入框上移过多或者无法回到正常位置,关于聊天室更加具体明确的写出参考学长的博客,「OC」实现简单的聊天室界面

总结

这个项目算是暑假中相当繁琐的一个,能更好的锻炼我们的各种传值方式和对各种控件的掌握

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/92260.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/92260.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/92260.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从案例学习cuda编程——线程模型和显存模型

1. cuda介绍CUDA&#xff08;Compute Unified Device Architecture&#xff0c;统一计算设备架构&#xff09;是NVIDIA推出的一种并行计算平台和编程模型。它允许开发者利用NVIDIA GPU的强大计算能力来加速计算密集型任务。CUDA通过提供一套专门的API和编程接口&#xff0c;使得…

进阶向:YOLOv11模型轻量化

YOLOv11模型轻量化详解:从理论到实践 引言 YOLO(You Only Look Once)系列模型因其高效的实时检测能力而广受欢迎。YOLOv11作为该系列的最新演进版本,在精度和速度上均有显著提升。然而,原始模型对计算资源的需求较高,难以在边缘设备或移动端部署。轻量化技术通过减少模…

2025-08 安卓开发面试拷打记录(面试题)

想跑路了&#xff0c;开始学八股&#xff0c;几个主动找的大厂试了下水&#xff0c;后续看情况更新。楼主一年经验&#xff0c;学的c被骗来干安卓&#xff0c;双非本科。2025-07-31 小鹏汇天 安卓开发一面synchronizedhandler视图刷新binderjvm垃圾回收内存泄漏排查glide缓…

风丘助力混合动力汽车工况测试:精准采集整车信号解决方案

一、背景 混合动力汽车是介于纯电动汽车与燃油汽车两者之间的一种新能源汽车。它既包含纯电动汽车无污染、启动快的优势&#xff0c;又拥有燃油车续航便捷、不受电池容量限制的特点。在当前环境下&#xff0c;混合动力汽车比纯电动汽车更符合目前的市场需求。 然而&#xff…

​​MCU程序的存储方式与存储区域大小要求​

程序的段的存储方式与存储区域大小要求 程序的存储和运行涉及 ROM&#xff08;Flash/非易失性存储器&#xff09; 和 RAM&#xff08;易失性存储器&#xff09; 的分配&#xff0c;不同段在存储和运行时具有不同的特性。以下是详细的分类和计算方式&#xff1a;1. 程序文件的存…

Lesson 31 Success story

Lesson 31 Success story 词汇 retire v.退休,退役[运动]去睡觉 构成:re-表示重复 tire v.感到累一tried a.累的 tyre n.轮胎 用法:retire from 单位 从…退休(过去时) 例句:他从学校退休了。 He retired from our school. retire例句: 1.他越来越老了&#xff0c;他即將退休。…

2025年8月4日私鱼创作平台v1.0.4公测版更新发布-完成大部分功能包含关注创作者以及发布作品及合集功能优雅草科技

2025年8月4日私鱼创作平台v1.0.4公测版更新发布-完成大部分功能包含关注创作者以及发布作品及合集功能优雅草科技 鲸鱼小说分销系统介绍 优雅草私鱼创作系统——产品介绍 系统概述 优雅草私鱼创作系统&#xff08;简称“私鱼”&#xff09;是一款专注于私域流量运营的垂直化…

鹧鸪云:光伏电站的“智慧中枢”,精准调控逆变器

光伏电站如星辰散落于大地&#xff0c;那些默默工作的逆变器便是每一处光芒的关键心脏。然而&#xff0c;分布广袤、设备众多&#xff0c;传统运维如盲人摸象&#xff0c;效率低下&#xff0c;故障难寻&#xff0c;白白流失宝贵电能。鹧鸪云光伏运维软件应时而生&#xff0c;它…

java中Reflection反射(一)

目录 一、概述 二、class类&#xff1a; 1、获取类的字节码文件&#xff1a; &#xff08;1&#xff09;方式一&#xff1a;直接通过一个class的静态变量class获取 &#xff08;2&#xff09;方式二&#xff1a;如果知道一个class的完整类名&#xff0c;可以通过静态方法Cl…

CVE-2021-1879

一、漏洞原理 CVE-2021-1879 是 IBM WebSphere Application Server 中存在的一个 路径遍历&#xff08;Path Traversal&#xff09; 漏洞&#xff0c;其核心原理为&#xff1a; ①WebSphere 在处理某些文件操作请求&#xff08;如下载、上传或配置文件读取&#xff09;时&#…

二进制签名查找器(Aho-Corasick 自动机):设计思路与实现原理(C/C++代码实现)

在逆向工程、恶意软件分析和二进制文件解析领域&#xff0c;快速准确地识别特定字节模式&#xff08;即“签名”&#xff09;是一项核心任务。本文将围绕一款基于PE-bear工具的二进制签名查找器&#xff0c;深入解析其设计思路、实现原理及相关技术背景&#xff0c;揭示其如何高…

後端開發技術教學(二) 條件指令、循環結構、定義函數

書接上回&#xff1a;後端開發技術教學(一) [附2025最新可用 phpstudy2018下載鏈接] -CSDN博客 必要資源&#xff1a; trae中文版下載網址: TRAE - The Real AI Engineer phpStudy 2018 : phpStudy - Windows 一键部署 PHP 开发环境 小皮出品 目录 一、條件指令 1.1 if() …

状压DP-基本框架

状压DP-基本框架一、状压DP的核心思想与适用场景1.1 问题特征1.2 核心思想1.3 与传统DP的对比二、位运算基础&#xff1a;状压DP的语法三、状压DP的基本框架3.1 步骤拆解3.2 通用代码模板四、经典案例详解4.1 旅行商问题&#xff08;TSP&#xff09;问题描述状压DP设计代码实现…

Web 端 AI 图像生成技术的应用与创新:虚拟背景与创意图像合成

随着 Stable Diffusion、Midjourney 等生成式 AI 模型的爆发,Web 端图像生成技术从“实验室demo”走向“工业化应用”。其中,虚拟背景替换(如视频会议的动态背景生成)和创意图像合成(如用户上传素材与 AI 生成元素的融合)成为最具代表性的场景,它们通过“文本描述→AI 生…

应急响应知识总结

应急响应 Windows系统 查账号 1、查看服务器是否有弱口令&#xff0c;远程管理端口是否对公网开放。 检查方法&#xff1a;据实际情况咨询相关服务器管理员。 2、查看服务器是否存在可疑账号、新增账号。 检查方法&#xff1a;打开 cmd 窗口&#xff0c;输入 lusrmgr.msc …

智慧水务赋能二次供水管理精细化转型:物联网驱动的全链路解决方案

随着我国城镇化率激增&#xff0c;高层建筑占比上升&#xff0c;二次供水系统已成为保障城市供水安全的核心环节。然而&#xff0c;传统管理模式面临设备老化、运维粗放、监管缺失等矛盾&#xff0c;在此背景下&#xff0c;《“十四五”节水型社会建设规划》明确要求推进二次供…

tsmc 5nm lvs之 short难搞的类型

1、M3层以上的层次发生的short&#xff0c;dengsity很高的情况下&#xff0c;两根信号net导致的short&#xff0c;删除其中一根然后ecoRoute fix不掉的情况下&#xff0c;该怎么办&#xff0c;可以尝试去cut 周围或者上方的power。 2、M1&#xff0c; M2由于cell 内部出pin&…

初识神经网络01——认识PyTorch

文章目录一、认识PyTorch1.1 PyTorch是什么1.2 安装PyTorch二、认识Tensor2.1 创建Tensor2.1.1 基本方式2.2.2 创建线性和随机张量2.2 Tensor属性2.2.1 切换设备2.2.2 类型转换2.3 Tensor与Numpy的数据转换2.3.1 张量转ndarray2.3.2 Numpy转张量2.4 Tensor常见操作2.4.1 取值2.…

Android UI 组件系列(十一):RecyclerView 多类型布局与数据刷新实战

博客专栏&#xff1a;Android初级入门UI组件与布局 源码&#xff1a;通过网盘分享的文件&#xff1a;Android入门布局及UI相关案例 链接: https://pan.baidu.com/s/1EOuDUKJndMISolieFSvXXg?pwd4k9n 提取码: 4k9n 引言 在 Android 应用中&#xff0c;RecyclerView 是最常用…

如何学习跨模态对齐(尤其是 CLIP 思想)

学习跨模态对齐&#xff08;尤其是CLIP思想&#xff09;需要结合理论基础、经典模型原理、实践复现和前沿扩展&#xff0c;以下是一套系统的学习路径&#xff0c;从入门到深入逐步展开&#xff1a; 一、先补基础&#xff1a;跨模态对齐的“前置知识” 跨模态对齐的核心是让图…