UIKit之图片浏览器

功能需求

实现一个图片浏览器,点击左右按钮可以切换背景图,且更新背景图对应的索引页和图片描述内容。

分析:

  • 实现一个UIView的子类即可,该子类包含多个按钮。

实现步骤:

  1. 使用OC语言,故创建cocoa Touch类型文件。Xcode会创建.h文件和.m文件:PicBrowserDemo类。
    在这里插入图片描述

  2. 图片资源导入:注意图片不要重名
    注意各项的类型:Root是Array,其余是Dictionary

  3. 实现该类。
    该类带有多个控件,令其继承UIView。
    a. 声明类的成员变量:在.h文件中定义:,类型是strong。
    该图片浏览器需要两个可显示文字内容但不可修改的Label、两个前后图片切换的按钮以及承载图片的视图。
    在.h 文件中:

@interface PicBrowserDemo : UIView
@property(strong, nonatomic) UIImageView  *imageView;
@property(strong, nonatomic) UILabel *label1;
@property(strong, nonatomic) UILabel *label2;
@property(strong, nonatomic) UIButton *btn1;
@property(strong, nonatomic) UIButton *btn2;
@end

b. 创建plist类型文件,直接在项目下创建,plist文件属于resource类型文件,在该栏目下可找到。
选择root类型为Array,而每个元素设置为字典,因为每个字典中存图片的名称和title(描述)。

c. .m 文件:

// 1 plist:信息填写
// 2 初始化各个组件,显示的信息以第一张为基准
// 3 nxt
// 4 pre
// 5 降低冗余,合并:pre、nxt函数#import "PicBrowserDemo.h"// 写私有属性:在这里
@interface PicBrowserDemo()
// assign、strong的区别: asign表示基本类型的变量
@property(nonatomic, strong) NSArray *pic;
@property(nonatomic, assign) int index;@end// 从plist中读取到的各图片信息集合@implementation PicBrowserDemo
-(instancetype) initWithFrame:(CGRect)frame{self = [super initWithFrame:frame];if(self){// 初始化5个组件_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, 230, 150, 150)];// 图片模式:放入如何显示的 按比例缩放,不会拉伸变形_imageView.contentMode = UIViewContentModeScaleAspectFit;// 初始化为pic中第一张图片NSDictionary *dict = self.pic[0];_imageView.image = [UIImage imageNamed:dict[@"icon"]];// 固定值写法://_imageView.image = [UIImage imageNamed:@"i1.png"];// label1:_label1 = [[UILabel alloc] initWithFrame:CGRectMake(80, 190, 150, 40)];_label2 = [[UILabel alloc] initWithFrame:CGRectMake(80, 380, 150, 40)];// text填内容_label1.text = [NSString stringWithFormat:@"%d/%ld", 1, self.pic.count];// 下面的label填入title_label2.text = dict[@"title"];// 填充方式fill_label1.textAlignment = NSTextAlignmentCenter;_label2.textAlignment = NSTextAlignmentCenter;// btn1_btn1 = [[UIButton alloc] initWithFrame:CGRectMake(30, 300, 50, 50)];_btn2 = [[UIButton alloc] initWithFrame:CGRectMake(230, 300, 50, 50)];// btn1[_btn1 setBackgroundImage:[UIImage imageNamed:@"zuo1.jpg"] forState:UIControlStateNormal];// btn2[_btn2 setBackgroundImage:[UIImage imageNamed:@"you1.png"] forState:UIControlStateNormal];// 绑定点击向前和向后[_btn1 addTarget:self action:@selector(changePages:) forControlEvents:UIControlEventTouchUpInside];//[_btn2 addTarget:self action:@selector(changePages:) forControlEvents:UIControlEventTouchUpInside];//        [_btn1 addTarget:self action:@selector(pre) forControlEvents:UIControlEventTouchUpInside];
//        //
//        [_btn2 addTarget:self action:@selector(nxt) forControlEvents:UIControlEventTouchUpInside];
//        // 用tags区分该切换前一张还是后一张_btn1.tag = 1;_btn2.tag = 2;[self addSubview: _imageView];[self addSubview: _btn1];[self addSubview: _btn2];[self addSubview: _label1];[self addSubview: _label2];}return self;
}// 重写属性pic的get方法懒加载:
/* 第一次调用一定为空,加载即可*/
- (NSArray *) pic{if(_pic == nil){// 获取plist的文件路径// nsBundle:获取手机上软件的安装路径,而非项目路径NSString *path = [[NSBundle mainBundle] pathForResource:@"pics" ofType:@"plist"];// 读取文件NSArray *array = [NSArray arrayWithContentsOfFile:path];NSLog(@"count:%ld", array.count);_pic = array;}return _pic;
}// 不需要参数:
- (void) changePages:(UIButton *)sender{switch (sender.tag) {case 1:_index--;break;case 2:_index++;break;}NSDictionary *dict = self.pic[self.index];// 上面的label填入页码_label1.text = [NSString stringWithFormat:@"%d/%ld", self.index+1, self.pic.count];// 下面的label填入title_label2.text = dict[@"title"];// 图片框填入图片:_imageView.image = [UIImage imageNamed:dict[@"icon"]];// 如果已经到了最后一张,则按钮切换为不允许点// 索引为末尾-1,则设置下一张按钮为不可点击// 没必要通过图片来设置,通过yes、no设置即可达到所需的灰色状态// 两条必须同时设置:否则会出现 翻到底再返回时,向右按钮仍然灰色self.btn2.enabled = !(_pic.count -1 == _index);self.btn1.enabled = !(0 == _index);
}// 加索引:
- (void) nxt{_index++;NSDictionary *dict = self.pic[self.index];// 上面的label:填入序号_label1.text = [NSString stringWithFormat:@"%d/%ld", self.index+1, self.pic.count];// 下面的label:填入标题_label2.text = dict[@"title"];// 图片框填入图片:_imageView.image = [UIImage imageNamed:dict[@"icon"]];// 如果已经到了最后一张,则按钮切换为不允许点// 索引为末尾-1,则设置下一张按钮为不可点击// 没必要通过图片来设置,通过yes、no设置即可达到所需的灰色状态self.btn2.enabled = !(_pic.count -1 == _index);self.btn1.enabled = !(0 == _index);
}//
- (void) pre{_index--;NSDictionary *dict = self.pic[self.index];// 上面的label:填入序号_label1.text = [NSString stringWithFormat:@"%d/%ld", self.index+1, self.pic.count];// 下面的label:填入标题_label2.text = dict[@"title"];// 图片框填入图片:_imageView.image = [UIImage imageNamed:dict[@"icon"]];// 如果为0,则设置向左不可点击且更换图片self.btn1.enabled = !(0 == _index);self.btn2.enabled = !(_pic.count -1 == _index);
}
@end

调用入口:

- (void)viewDidLoad {[super viewDidLoad];//[self test_Common_arrtibute];[self testPicBrowser];
}-(void) testPicBrowser{PicBrowserDemo *browserView = [[PicBrowserDemo alloc] initWithFrame:CGRectMake(50, 80, 300 ,700)];//[browserView setBackgroundColor: [UIColor blueColor]];[self.view addSubview:browserView];}
  1. 效果展示
  1. 首页只可向右
  2. 尾页只可向左

在这里插入图片描述
在这里插入图片描述

要注意的问题以及犯错

  1. 关于懒加载:
    设置变量同名的函数,实则为setter,判断变量指向为空,则做初始化获取操作,后续再利用都不需要,此为懒加载方式。
  1. 关于plist加载:
    使用bundle接口,, 通过plist文件名即可,该底层原理是使用了安装APP后的文件结构来获取文件,而非运行工程的目录结构。
  1. plist总是读取为空
    我的plist获取方式是读取Array接口,而我的plist中root设置为dictionary类型,因此接口不对应,获取错误了。改root为array类型即可。
  1. 初始化index报错
    switch中,tag为2是向右点击,所以应该index++。
  1. 图片浏览器初始化:
    按pic第一张的图片和title初始化即可。

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

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

相关文章

运用MongoDB Atlas释放开发者潜能同时把控成本

在当下的商业环境中,不可预测性已经成为常态,工程团队负责人必须在把控不可预测性和优化IT成本的双重挑战下谋求平衡。 咨询公司德勤2024 MarginPLUS调查收集了300多位企业负责人的见解,报告中重点介绍了面对动荡的全球经济环境,…

每日5题Day3 - LeetCode 11 - 15

每一步向前都是向自己的梦想更近一步,坚持不懈,勇往直前! 第一题:11. 盛最多水的容器 - 力扣(LeetCode) class Solution {public int maxArea(int[] height) {//这道题比较特殊,因为两边是任意…

AniPortrait详细讲解以及完整搭建流程(有问题留言)

AniPortrait是一款真实感人像动画的音频驱动合成的AI程序。 下面是它的github源码: GitHub - Zejun-Yang/AniPortrait: AniPortrait: Audio-Driven Synthesis of Photorealistic Portrait AnimationAniPortrait: Audio-Driven Synthesis of Photorealistic Portrait Animati…

VC++6.0 ListViewReport报表使用例子

操作步骤: 1,拖一个ListContorl控件 2,修改ID名称 3,设置Report样式 3,加入初始化代码 void CDuplicatefilesclearDlg::InitlizationListView() {CListCtrl *lstVew (CListCtrl*)GetDlgItem(IDC_LIST_Main);lstVew-&…

Shell之高效文本处理命令

目录 一、排序命令—sort 基本语法 常用选项 二、去重命令—uniq 基本语法 常用选项 三、替换命令—tr 基本语法: 常用选项 四、裁剪命令—cut 基本语法: 常用选项 字符串分片 五、拆分命令—split 基本语法: 六、 文件…

kafka用java收发消息

用java客户端代码来对kafka收发消息 具体代码如下 package com.cool.interesting.kafka;import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; i…

Vue 之 后台管理系统的权限路由的管理

目录 前言实现理解三者的概念以及之间的关联账号(用户)角色菜单 用户权限授权相关概念实现代码实现登录跳转路由,路由守卫中进行权限验证按钮权限封装指令:调用(其中一个页面参考) 思路,操作流程…

景源畅信数字:做抖音切片的方法分享?

一提起抖音切片,很多人可能会想到那些让人眼前一亮的短视频。它们通常短小精悍,内容丰富多彩,能够迅速吸引观众的注意力。但是,如何制作出这样的切片视频呢?这就是我们今天要探讨的问题。 一、选材与剪辑 制作抖音切片&#xff0…

年度更新!统信UOS服务器版V20(1070)超越期待

不负广大客户期待! 统信UOS服务器版V20(1070)年度首更 功能更强大、性能更卓越、生态更丰富 助您畅享安全、便捷、高效的产品和服务 新平台,新生态 统信UOS服务器版始终坚持进行生态适配,目前已支持超过百万种兼容…

某能源集团电力公司搭建数据报表中心,实现采集填报分析一体化

​在当今这个信息爆炸的时代,数据已成为企业最宝贵的财富,越来越多的企业开始重视数据的积累和归集。在企业日常生产和工作过程中,会产生绵延不断的数据,但这些数据往往没有统一的记录、归纳和整理,或者录入了系统却分…

电子邮箱是什么?付费电子邮箱和免费电子邮箱有什么区别?

注册电子邮箱前,有付费电子邮箱和免费电子邮箱两类选择。付费的电子邮箱和免费的电子邮箱有什么区别呢?区别主要在于存储空间、功能丰富度和售后服务等方面,本文将为您详细介绍。 一、电子邮箱是什么? 电子邮箱就是线上的邮局&a…

【传知代码】VRT: 关于视频修复的模型(论文复现)

前言:随着数字媒体技术的普及,制作和传播视频内容变得日益普遍。但是,视频中由于多种因素,例如传输、存储和录制设备等,经常出现质量上的问题,如图像模糊、噪声干扰和低清晰度等。这类问题对用户的体验和观…