【iOS】暑期第一周——ZARA app仿写

目录

  • 前言
  • 无限轮播图
  • 分栏控件和滚动视图
  • 自定义cell
  • 遇到的问题
    • 调整图标大小
    • 单元格附件视图设置
  • 总结

前言

  暑假学习的第一周任务是对ZARA app进行仿写,充分运用之前学习的Objective-C语言和UI控件。我在编写demo的过程中遇到了一些问题,特写该博客作为学习笔记。

无限轮播图

  刚打开ZARA app,我们在首页可以看到有一个商品展示的自动轮播图,无论是用图片两侧的按钮还是自动轮播,商品图片在视觉上给人一种无限循环轮播的效果。无限轮播图实质上是一个UIScrollView滚动视图控件,我们这里可以令ViewController遵循UIScrollViewDelegate协议,然后在

– (void)scrollViewDidScroll:(UIScrollView *)scrollView {}

方法里实现就行。方法里的编写思路是让他滚动到第六张图(注:我首页的无限轮播图为五张),也就是最后一张图时,让第一张图成为他的下一张图。

【代码如下】

//无限轮播实现部分
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {CGFloat contentOffsetX = scrollView.contentOffset.x;CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;CGFloat contentWidth = scrollView.contentSize.width;if (contentOffsetX >= contentWidth - screenWidth) {[scrollView setContentOffset:CGPointMake(screenWidth, 0) animated:NO];self.page.currentPage = 0;} else if (contentOffsetX <= 0) {[scrollView setContentOffset:CGPointMake(contentWidth - 2 * screenWidth, 0) animated:NO];self.page.currentPage = 4;} else {self.page.currentPage = (contentOffsetX / screenWidth) - 1;}
}

至于自动轮播,只需要写一个自动播放的函数,添加视图偏移和控制视图滚动的定时器就可以了,下面给出代码示例:

//自动轮播实现部分(定时器)
- (void)autoScroll
{CGFloat width = [UIScreen mainScreen].bounds.size.width;[_scrollView setContentOffset:CGPointMake(_scrollView.contentOffset.x + width, 0) animated:YES];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{[self.timer invalidate];self.timer = nil;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(autoScroll) userInfo:nil repeats:YES];
}

至于图片左右的按钮调节部分,只要创建左右两个按钮。调节好Button在视图里的放置位置,为按钮添加事件函数(即按下左按钮,当到第一张图片时,如果继续按下左按钮,将会把滚动视图偏移到最后一张;同理,按下右按钮,当到最后一张图片时,如果继续按下右按钮,将会把滚动视图偏移到第一张),这里主要用到UIPageControl控件。下面给出按下按钮触发的事件函数代码:

//按压按钮触发事件函数
- (void)pressLeft
{[self.timer invalidate];self.timer = nil;int nowPage = _scrollView.contentOffset.x / self.view.frame.size.width;_scrollView.contentOffset = CGPointMake(self.view.frame.size.width * (nowPage - 1), 0);if (nowPage == 1) {_scrollView.contentOffset = CGPointMake(self.view.frame.size.width * 5, 0);}self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(autoScroll) userInfo:nil repeats:YES];
}
- (void)pressRight
{[self.timer invalidate];self.timer = nil;int nowPage = _scrollView.contentOffset.x / self.view.bounds.size.width;_scrollView.contentOffset = CGPointMake( self.view.bounds.size.width * (nowPage + 1), 0);if (nowPage == 6) {_scrollView.contentOffset = CGPointMake(self.view.bounds.size.width * 4, 0);}self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(autoScroll) userInfo:nil repeats:YES];
}

【效果图】
首页的效果图如下:
在这里插入图片描述

分栏控件和滚动视图

  在商品页面,主要是实现滚动视图和分栏控件,并实现分栏控件与滚动视图的同步——在点击分栏控件时,滚动视图会随之变到相应的位置,在滑动视图时,分栏控件同理,一般用于在商品分类展示时,商品类名与图片相对应。思路就是添加代码将滚动视图的偏移量转化成分栏控件的索引,同理在滚动视图也添加受控件索引的偏移函数。下面给出代码示例:

- (void)valueChanged
{NSInteger index = _segControl.selectedSegmentIndex;CGFloat x = index * self.view.frame.size.width;_scrollView.contentOffset = CGPointMake(x, _scrollView.contentOffset.y);
}- (void)scrollViewDidScroll:(UIScrollView *)scrollView {CGFloat offsetX = scrollView.contentOffset.x;CGFloat width = self.view.frame.size.width;NSInteger index = offsetX / width + 0.5;if (_segControl.selectedSegmentIndex != index) {_segControl.selectedSegmentIndex = index;}
}

效果图如下:
在这里插入图片描述

自定义cell

  用户页面本质上就是一个自定义的tableViewCell视图,自定义cell的使用,这里注意不同的位置,cell单元格的高度和内容不同,通过索引来区别和分类进行单元格的绘制都可以。
  除此之外,还需要实现用户在第一个单元格时,进入自己的个人信息页面,只需要给第一个单元格添加事件,该事件需要推出一个新的界面。
这里主要给出新界面的cell函数:

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];if ([self.reuseIdentifier isEqualToString: @"cell"]) {self.imageView2 = [[UIImageView alloc] init];[self.contentView addSubview: _imageView2];self.label1 = [[UILabel alloc] init];[self.contentView addSubview:_label1];self.label2 = [[UILabel alloc] init];[self.contentView addSubview:_label2];}return self;
}

效果图:
在这里插入图片描述
点击第一个单元格后:
在这里插入图片描述

遇到的问题

  在仿写时,遇到的主要问题有两个。第一个是在网上下载的图标通常不是我们想要的尺寸,我们如何得到自己想要的image的大小并重新呈现在画布上;第二个问题是,在用户页面,用户点击单元格选中后,单元格呈现出被点击的灰色状态,如何在用户松手后变回原来的状态。

调整图标大小

下面以商品页面的图标为例,给出代码:

    UIImage *tabImage = [UIImage imageNamed:@"shopping.png"];CGSize newSize = CGSizeMake(30, 30);UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);[tabImage drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();

这里通过使用 UIGraphicsBeginImageContextWithOptions 和相关方法,可以调整图像的大小,并将其用作 UITabBarItem 的图标。
drawInRect:方法中的参数:newSize 是上下文的大小,NO 表示图像是否不透明(透明),0.0 表示使用设备的默认缩放因子。

单元格附件视图设置

一般要用到以下两行代码(这里以cell为示例):

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;cell.selectionStyle = UITableViewCellSelectionStyleDefault;

下面给出解释:

  • accessoryType 属性用于设置单元格右侧显示的附件视图类型。UITableViewCellAccessoryDisclosureIndicator 是一个右箭头图标,通常用于指示点击该单元格会导航到另一个视图控制器。
    其他可用的 UITableViewCellAccessoryType 类型包括:

UITableViewCellAccessoryNone: 无附件视图
UITableViewCellAccessoryCheckmark: 勾选标记
UITableViewCellAccessoryDetailButton: 详情按钮
UITableViewCellAccessoryDetailDisclosureButton: 详情披露按钮

  • selectionStyle 属性用于设置单元格被选中时的样式。
    UITableViewCellSelectionStyleDefault 是默认的选择风格,通常是灰色背景。
    其他可用的 UITableViewCellSelectionStyle 类型包括:>

UITableViewCellSelectionStyleNone: 无选择风格(即单元格被点击时不会改变背景)
UITableViewCellSelectionStyleBlue: 蓝色背景(已被废弃)
UITableViewCellSelectionStyleGray: 灰色背

总结

  因为离UI学习过去了快两个月,对于部分OC和UI知识有所遗忘,刚开始编写demo会比较慢,在仿写ZARA中比较重要的是自定义cell和TableView,同时也要注意页面的布局,尽量让页面看起来美观。总之,ZARA是UI学习完的基础练手项目,不仅简单回顾了UI的基础知识,也为后面网易云app仿写作了铺垫。

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

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

相关文章

LLM与搜索推荐

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

VScode连接服务器免密登录

1、生成 SSH 密钥对 打开终端并输入以下命令生成 SSH 密钥对&#xff1a; 直接搜索 cmd&#xff0c;然后输入&#xff1a; ssh-keygen -t rsa -b 4096 一直回车就好了 这时公钥存储在/Users/你的用户名/.ssh/id_rsa.pub文件里&#xff0c;私钥存储在/Users/你的用户名/.ss…

简单的数据结构:栈

1.栈的基本概念 1.1栈的定义 栈是一种线性表&#xff0c;只能在一端进行数据的插入或删除&#xff0c;可以用数组或链表来实现&#xff0c;这里以数组为例进行说明 栈顶 &#xff1a;数据出入的那一端&#xff0c;通常用Top表示 栈底 :相对于栈顶的另一端&#xff0c;也是固…

黑马头条vue2.0项目实战(一)——项目初始化

1. 图标素材&#xff08;iconfont简介&#xff09; 制作字体图标的工具有很多&#xff0c;推荐使用&#xff1a;iconfont-阿里巴巴矢量图标库。 注册账户 创建项目 可以根据项目自定义 class 前缀 上传图标到项目 生成链接&#xff0c;复制 css 代码&#xff0c;在项目中使用…

【知识梳理】Shell的变量计算

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 Shell中有很多变量的计算&#xff0c;会用到多种运算符。例如这几种&#xff1a; 1. Shell中常见的算术运算符 运算符意义&…

github-page静态网页将字符串写入github库中文本文档

🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!! 问题描述 github-page静态…

Natutre Methods|单细胞+空间转录,值得去复现的开源单细胞分析pipeline

肺癌是全球第二大最常见的癌症&#xff0c;也是癌症相关死亡的主要原因。肿瘤生态系统具有多种免疫细胞类型。尤其是髓系细胞&#xff0c;髓系细胞普遍存在&#xff0c;并且在促进疾病方面发挥着众所周知的作用。该篇通过单细胞和空间转录组学分析了 25 名未经治疗的腺癌和鳞状…

网络模型优化——从参数向量到性能提升的最优化之旅

网络模型优化——从参数向量到性能提升的最优化之旅 网络模型优化的核心作用 组件/步骤描述参数向量网络模型中的可学习部分&#xff0c;决定了模型的输出泛函最优化通过调整参数向量以最小化或最大化某个目标函数的过程目标函数用于评估模型性能的指标&#xff0c;如损失函数…

【初阶数据结构篇】顺序表的实现(赋源码)

文章目录 本篇代码位置顺序表和链表1.线性表2.顺序表2.1 概念与结构2.2分类2.2.1 静态顺序表2.2.2 动态顺序表 2.3 动态顺序表的实现2.3.1动态顺序表的初始化和销毁及打印2.3.2动态顺序表的插入动态顺序表的尾插动态顺序表的头插动态顺序表的在指定位置插入数据 2.3.3动态顺序表…

区块链——hardhat使用

一、引入hardhat yarn add --dev hardhat // 引入验证合约的插件 yarn add --dev nomicfoundation/hardhat-verify 二、创建hardhat项目 yarn hardhat 三、编写我们的合约 四、编译我们的合约 yarn hardhat compile 五、编写脚本部署合约以及验证合约 // 获取hardhat环境对象 c…

Python操作Redis指南

文本主要介绍使用Python中的redis-py库来操作Redis数据库&#xff0c;包括安装必要的包、建立和关闭连接、执行增删改查操作以及处理可能的异常。这些操作将在Python应用程序中与Redis数据库进行有效的交互。 一. 简介和包的安装 Redis是一种开源的内存数据结构存储&#xff…

Jmeter混合压测(2407)

一 压测需求&#xff1a; 电商作为服务端&#xff0c;至少需要满足并发量,QPS:100/s,TPS:20/s。例如场景&#xff1a; 电商交易中&#xff0c;商品图片请求量最多&#xff0c;电商服务端需要满足并发请求查询图片信息。各家可能会并发请求同一家电商商品、订单等内容。 二 压…

代码随想录算法训练营day7 | 454.四数相加II、383.赎金信、15.三数之和、18.四数之和

文章目录 454.四数相加II思路 383.赎金信思路 15.三数之和思路剪枝去重 18.四数之和思路剪枝去重复习&#xff1a;C中的类型转换方法 总结 今天是哈希表专题的第二天 废话不多说&#xff0c;直接上题目 454.四数相加II 建议&#xff1a;本题是 使用map 巧妙解决的问题&#x…

HarmonyOS(45) 控件拖动或者拖拽PanGesture

PanGesture实现控件拖动的效果&#xff0c;通过拖动的坐标位置调用position或者translate方法来更新UI的位置。效果见下图&#xff1a; 具体代码如下&#xff1a; // xxx.ets Entry Component struct PanGestureExample {State offsetX: number 0State offsetY: number 0pos…

【AI学习指南】轻量级模型-用 Ollama 轻松玩转本地大模型

目录 探索 最小的AI模型 发现 其他轻量级模型 用 Ollama 轻松玩转本地大模型 本地大模型 Ollama 快速上手 安装 手动安装 下载ollama二进制文件 添加 Ollama 作为启动服务(推荐) 安装 CUDA 驱动程序(可选 - 适用于 Nvidia GPU) 安装 ROCm(可选 - 对于 Radeo…

Typesript的type和interface的异同?

详解TypeScript中type与interface的区别_javascript技巧_脚本之家 一、相同的地方 1、都可以用来定义对象&#xff0c;描述函数 我们在用typescript开发的时候经常要用到数据类型定义&#xff0c;比如我们写一个接口或者函数的时候定义传参数据类型及字段等。这样子方便知道这…

代码随想录day21 二叉树最后一天 || 669修剪二叉树 108将有序数组转变为平衡搜索二叉树 538把搜索二叉树变为累加二叉树

669修剪二叉树 力扣题目链接 题目描述&#xff1a; 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果…

K8s 核心组件——API Server

1. Kubernetes API Server 概述 1.1 基本概念 Kubernetes API Server&#xff08;API Server&#xff09;是 Kubernetes 的核心组件之一&#xff0c;负责暴露 Kubernetes API 给用户和客户端&#xff0c;接收和处理来自客户端的请求&#xff0c;并将其存储到 etcd 中。Kubern…

花几千上万学习Java,真没必要!(三十一)

集合&#xff1a; 1、数组的特性&#xff1a; 2、ArrayList&#xff08;动态数组&#xff09;&#xff1a; 测试代码1&#xff1a; package listtest.com; import java.util.ArrayList; import java.util.List; public class HashCodesArrayList { public static void ma…

深入分析 Android ContentProvider (六)

文章目录 深入分析 Android ContentProvider (六)ContentProvider 的性能优化和实践案例&#xff08;续&#xff09;1. 性能优化技巧&#xff08;续&#xff09;1.6. 使用批量插入优化性能示例&#xff1a;批量插入实现 1.7. 使用 Projections 优化查询示例&#xff1a;使用 Pr…