UIKit之图片浏览器

news2024/9/22 13:42:52

功能需求

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

分析:

  • 实现一个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.coloradmin.cn/o/1679847.html

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

相关文章

【JavaScript】WeakMap 和 WeakSet

Map Map 用于存储键值对。 添加属性: 使用 Map 的 set() 方法可以向 Map 对象中添加键值对。例如: const map new Map(); map.set(key1, value1); map.set(key2, value2);通过二维数组快速创建 map 键值对。 let arr [[1, 2],[2, 3],[3, 4]]let map …

window10下安装ubuntu系统以及docker使用

window10下安装ubuntu系统以及docker使用 1. 启用适用于Linux的Windwos子系统2.下载Linux内核更新包3.将 WSL 2 设置为默认版本4.安装Ubuntu<br />直接去Microsoft store里面直接搜索Ubuntu进行安装。5.可能出现的问题1.win10启动ubuntu报错 参考的对象类型不支持尝试的操…

2024中国应急(消防)品牌巡展西安站成功召开!惊喜不断

消防品牌巡展西安站 5月10日&#xff0c;由中国安全产业协会指导&#xff0c;中国安全产业协会应急创新分会、应急救援产业网联合主办&#xff0c;陕西消防协会协办的“一切为了安全”2024年中国应急(消防)品牌巡展-西安站成功举办。该巡展旨在展示中国应急&#xff08;消防&am…

ABC352编程笔记

ABC352 编程笔记 题意&#xff1a;输入&#xff0c;四个数 a , b , c , d a,b,c,d a,b,c,d&#xff0c;若 d d d 在 c , d c,d c,d 之间&#xff0c;则输出 Yes&#xff0c;否则输出 No。 正解&#xff1a;直接判断。 #include <bits/stdc.h> //#define int long lo…

大数据比赛-环境搭建(二)

一、ubuntu安装google 1、下载google的Linux安装版 链接&#xff1a;https://pan.baidu.com/s/1w4Hsa1wbJDfC95fX2vU_1A 提取码&#xff1a;xms6 或者&#xff1a;Google Chrome 64bit Linux版_chrome浏览器,chrome插件,谷歌浏览器下载,谈笑有鸿儒 (chromedownloads.net) …

docker-java 操作docker

部署docker 10分钟学会Docker的安装和使用_docker安装-CSDN博客文章浏览阅读2.5w次&#xff0c;点赞44次&#xff0c;收藏279次。文章目录Docker简介Docker安装Windows安装Linux安装CentOS安装Ubuntu安装最近花了些时间学习docker技术相关&#xff0c;在此做一些总结&#xff0…

静态IP代理:网络世界的隐秘通道

在数字化时代&#xff0c;网络安全和隐私保护日益受到重视。静态IP代理作为一种网络服务&#xff0c;为用户提供了一个稳定且可预测的网络连接方式&#xff0c;同时保护了用户的在线身份。本文将从五个方面深入探讨静态IP代理的概念、优势、应用场景、技术实现以及选择时的考量…

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

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

【JAVA】嵌入式软件工程师-2025校招必备-详细整理

一、Java 基础 1.JDK 和 JRE 有什么区别&#xff1f; jdk&#xff1a;java development kit jre&#xff1a;java runtime Environment jdk是面向开发人员的&#xff0c;是开发工具包&#xff0c;包括开发人员需要用到的一些类。 jre是java运行时环境&#xff0c;包括java虚拟机…

困惑点记录

【第十章 总结思考】CIM之我见 - 知乎

STK中的光照计算模型

本文简要阐述STK中光照计算的模型。 在航天任务中&#xff0c;通常需要分析地面站、飞行器在一定时间内的光照情况&#xff0c;具体包括&#xff1a; 地面站处在光照区和阴影区的具体时间范围&#xff1b;考虑地形遮挡后&#xff0c;地面站的光照区和阴影区的变化情况&#x…

解决kali Linux安装后如何将语言修改为中文

开启虚拟机 用root用户进入终端 进入终端执行dpkg-reconfigure locales命令 选择en_US.UTF-8 UTF-8选项&#xff0c;按空格键将其取消。 选择zh_CN.UTF-8 UTP-8&#xff0c;按空格选择&#xff0c;按tab键选择ok。 选择zh_CN.UTF-8字符编码&#xff0c;按tab键选择ok&#xff0…

【漏洞复现】Secnet-智能路由系统 actpt_5g.data信息泄露

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司(简称“安网通信”)的无线AP管理系统 0x02 漏洞描述 Secnet智能路由系统 acipt 5g.data 接口存在信息泄露漏洞&#xff0c;未经身份验证的远程攻击者可以利用此漏洞获取系统账户名密码等重要凭据&#xff…

社区服务用工具建立与居民的强关系

在数字化时代的浪潮下&#xff0c;社区服务不再局限于传统的面对面交流模式&#xff0c;而是借助互联网医疗健康服务应用&#xff0c;尤其是智慧康养服务平台&#xff0c;构建起了与居民之间更为紧密、便捷的联系。这种新型的社区服务模式&#xff0c;不仅提升了服务效率&#…

wsl2安装rancher并导入和创建k8s集群

环境准备 安装wsl2点击此文]ubuntu20.04安装docker 点击此文,安装完成后docker镜像仓库改成阿里云镜像加速地址.如果不熟请点击此文 docker 安装rancher 启动wsl,根据官方文档以root身份执行 sudo docker run -d --restartunless-stopped -p 80:80 -p 443:443 --privileged …

第13节 第二种shellcode编写实战(2)

我最近在做一个关于shellcode入门和开发的专题课&#x1f469;&#x1f3fb;‍&#x1f4bb;&#xff0c;主要面向对网络安全技术感兴趣的小伙伴。这是视频版内容对应的文字版材料&#xff0c;内容里面的每一个环境我都亲自测试实操过的记录&#xff0c;有需要的小伙伴可以参考…

错误: 找不到或无法加载主类问题(已解决)

今天在虚拟机中安装了idea2023.2的版本&#xff0c;运行代码时发现错误找不到主类&#xff01; 直接说结论&#xff1a; 我先clean了一下target&#xff0c;然后重新build&#xff0c;发现maven报错了&#xff0c;idea2023.2默认使用了内置的maven&#xff0c;然后我切换了一下…

Shell之(数组)

目录 一、shell数组 1.数组的定义 2.定义数组的方法 第一种 第二种 第三种 第四种 3.数组分片 4. 数组字符替换 临时替换 永久替换 5.删除数组 删除指定的下标 删除整组 6.数组遍历和重新定义 7.数组追加元素 方式一&#xff1a;指定位置添加 方法二&a…

【JAVA入门】Day05 - 面向对象

【JAVA入门】Day05 - 面向对象 文章目录 【JAVA入门】Day05 - 面向对象一、对象的设计和使用1.1 类和对象1.2 类的分类 二、封装三、private 关键字四、this 关键字五、构造方法六、JavaBean七、对象的内存图7.1 一个对象的内存图7.2 两个对象的内存图7.3 两个引用指向同一个对…