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

目录

前言

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

无限轮播图

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

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

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

【代码如下】

objectivec 复制代码
//无限轮播实现部分
- (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;
    }
}

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

objectivec 复制代码
//自动轮播实现部分(定时器)
- (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控件。下面给出按下按钮触发的事件函数代码:

objectivec 复制代码
//按压按钮触发事件函数
- (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];
}

【效果图】

首页的效果图如下:

分栏控件和滚动视图

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

objectivec 复制代码
- (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函数:

objectivec 复制代码
- (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的大小并重新呈现在画布上;第二个问题是,在用户页面,用户点击单元格选中后,单元格呈现出被点击的灰色状态,如何在用户松手后变回原来的状态。

调整图标大小

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

objectivec 复制代码
    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为示例):

objectivec 复制代码
    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仿写作了铺垫。

相关推荐
神奇夜光杯3 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue5 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧7 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
测试界的酸菜鱼18 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
Mephisto.java22 分钟前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
晨曦_子画27 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend36 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
希言JY1 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
残月只会敲键盘1 小时前
php代码审计--常见函数整理
开发语言·php