
使用UIImageView、UILabel、UIButton实现一个综合小案例
功能分析
(1)点击箭头切换序号、图片、描述 (2)如果是首张图片,左边箭头不能点击 (3)如果是尾张图片,右边箭头不能点击步骤分析
(1)搭建UI界面 (2)监听按钮点击切换序号、图片、描述

1. 界面分析
1> 需要读取或修改的属性的控件
// 序号标签
// 图片
// 图片描述
// 左边按钮
// 右边按钮
2> 需要监听响应事件的对象,需要添加监听方法
// 左边按钮
// 右边按钮
uiimage 是图片,不是控件,他的父类为NSObject,UIImageView是加载图片的控件,父类为UIView
完全的代码编写界面(复习回忆)
#import "ViewController.h"
@interface ViewController ()
//序号标签
@PRoperty (nonatomic, strong) UILabel *noLabel;
//图片
@property (nonatomic, strong) UIImageView *icon;
//图片描述
@property (nonatomic, strong) UILabel *descLabel;
//左边按钮
@property (nonatomic, strong) UIButton *leftButton;
//右边按钮
@property (nonatomic, strong) UIButton *rightButton;
@end
@implementation ViewController
//初始化工作
//viewDidLoad是视图加载完成后调用的方法,通常在此方法中执行视图控制器的初始化工作
- (void)viewDidLoad {
[super viewDidLoad];
//实例化控件
//1、序号标签的编写
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 320, 40)];
label.text = @"1/5";
//居中对齐
label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label];
//记录改变
self.noLabel = label;
//2、图片控件
CGFloat imageW = 200;
CGFloat imageH = 200;
CGFloat imageX = (320 - imageW) / 2;
CGFloat imageY = 80;
//实例化一个图像视图
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageX, imageY, imageW, imageH)];
//实例化一个图像
UIImage *image = [UIImage imageNamed:@"biaoqingdi"];
//把图片显示到imageView
imageView.image = image;
[self.view addSubview:imageView];
//记录下改变
self.icon = imageView;
//3、图片描述 label 控件
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, 300, 80)];
label1.text = @"发发发";
//居中对齐
label1.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label1];
//记录改变
self.descLabel = label1;
//4、左边的按钮
UIButton *leftBtn = [[UIButton alloc] init];
//设置按钮的背景图
[leftBtn setBackgroundImage:[UIImage imageNamed:@"left_normal"] forState:UIControlStateNormal];
[leftBtn setBackgroundImage:[UIImage imageNamed:@"left_highlighted"] forState:UIControlStateHighlighted];
//设置按钮的大小
leftBtn.frame = CGRectMake(0, 0, 40, 40);
//设置按钮的位置
leftBtn.center = CGPointMake(self.icon.frame.origin.x / 2, self.icon.center.y);
[self.view addSubview:leftBtn];
self.leftButton = leftBtn;
//5、右边的按钮
UIButton *rightBtn = [[UIButton alloc] init];
//设置按钮的背景图
[rightBtn setBackgroundImage:[UIImage imageNamed:@"right_normal"] forState:UIControlStateNormal];
[rightBtn setBackgroundImage:[UIImage imageNamed:@"right_highlighted"] forState:UIControlStateHighlighted];
//设置按钮的大小
rightBtn.frame = CGRectMake(0, 0, 40, 40);
//设置按钮的位置
rightBtn.center = CGPointMake(self.view.frame.size.width - self.icon.frame.origin.x / 2, self.icon.center.y);
[self.view addSubview:rightBtn];
self.leftButton = rightBtn;
}
@end
完整的代码如下:
#import "ViewController.h"
@interface ViewController ()
//序号标签
@property (nonatomic, strong) UILabel *noLabel;
//图片
@property (nonatomic, strong) UIImageView *icon;
//图片描述
@property (nonatomic, strong) UILabel *descLabel;
//左边按钮
@property (nonatomic, strong) UIButton *leftButton;
//右边按钮
@property (nonatomic, strong) UIButton *rightButton;
//图片索引,index默认是0
@property (nonatomic, assign) int index;
/**设置一个图像的数组*/
//新的注释,可以显式中文
@property (nonatomic, strong) NSArray *imageList;
/*
@property
自动为我们生成 set,get 方法的声明和实现
带下划线的成员变量
*/
@end
@implementation ViewController
//控件懒加载
//不需要每次都在 viewdidload 里实例化数组,只要在需要的时候实例化即可
//重写 get 方法
- (NSArray *)imageList
{
//只有第一次调用imageList 的 getter 方法的时候,如果为空,那么再实例化并建立数组,其他时候,直接返回成员变量
if (_imageList == nil) {
//使用字典
NSDictionary *dict1 = @{@"name" : @"biaoqingdi", @"desc" : @"表情"};
NSDictionary *dict2 = @{@"name" : @"bingli", @"desc" : @"病历"};
NSDictionary *dict3 = @{@"name" : @"chiniupa", @"desc" : @"吃牛扒"};
NSDictionary *dict4 = @{@"name" : @"danteng", @"desc" : @"蛋疼"};
NSDictionary *dict5 = @{@"name" : @"wangba", @"desc" : @"王八"};
self.imageList = @[dict1, dict2, dict3, dict4, dict5];
}
return _imageList;
}
//初始化工作
//viewDidLoad是视图加载完成后调用的方法,通常在此方法中执行视图控制器的初始化工作
- (void)viewDidLoad {
[super viewDidLoad];
//实例化控件
//1、序号标签的编写
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 320, 40)];
// label.text = @"1/5";
//居中对齐
label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label];
//记录改变
self.noLabel = label;
//2、图片控件
CGFloat imageW = 200;
CGFloat imageH = 200;
CGFloat imageX = (320 - imageW) / 2;
CGFloat imageY = 80;
//实例化一个图像视图
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageX, imageY, imageW, imageH)];
//实例化一个图像
// UIImage *image = [UIImage imageNamed:@"biaoqingdi"];
//把图片显示到imageView
// imageView.image = image;
//把图像增加到 view
[self.view addSubview:imageView];
//记录下改变
self.icon = imageView;
//3、图片描述 label 控件
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, 300, 80)];
// label1.text = @"发发发";
//居中对齐
label1.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label1];
//记录改变
self.descLabel = label1;
//4、左边的按钮
UIButton *leftBtn = [[UIButton alloc] init];
//设置按钮的背景图
[leftBtn setBackgroundImage:[UIImage imageNamed:@"left_normal"] forState:UIControlStateNormal];
[leftBtn setBackgroundImage:[UIImage imageNamed:@"left_highlighted"] forState:UIControlStateHighlighted];
//设置按钮的大小
leftBtn.frame = CGRectMake(0, 0, 40, 40);
//设置按钮的位置
leftBtn.center = CGPointMake(self.icon.frame.origin.x / 2, self.icon.center.y);
[self.view addSubview:leftBtn];
//设置监听
[leftBtn addTarget:self action:@selector(leftClick) forControlEvents:UIControlEventTouchUpInside];
self.leftButton = leftBtn;
//5、右边的按钮
UIButton *rightBtn = [[UIButton alloc] init];
//设置按钮的背景图
[rightBtn setBackgroundImage:[UIImage imageNamed:@"right_normal"] forState:UIControlStateNormal];
[rightBtn setBackgroundImage:[UIImage imageNamed:@"right_highlighted"] forState:UIControlStateHighlighted];
//设置按钮的大小
rightBtn.frame = CGRectMake(0, 0, 40, 40);
//设置按钮的位置
rightBtn.center = CGPointMake(self.view.frame.size.width - self.icon.frame.origin.x / 2, self.icon.center.y);
[self.view addSubview:rightBtn];
//设置监听
[rightBtn addTarget:self action:@selector(rightClick) forControlEvents:UIControlEventTouchUpInside];
self.rightButton = rightBtn;
[self change];
}
- (void)change
{
//更具 self.index 来显示序号标签,图形,,描述
self.noLabel.text = [NSString stringWithFormat:@"%d / %d", self.index + 1, 5];
self.icon.image = [UIImage imageNamed:self.imageList[self.index][@"name"]];
self.descLabel.text = self.imageList[self.index][@"desc"];
self.leftButton.enabled = (self.index != 0);
self.rightButton.enabled = (self.index != 4);
}
//left
- (void)leftClick
{
self.index--;
[self change];
}
//right
- (void)rightClick
{
self.index++;
[self change];
}
@end
小结:
/**设置一个图像的数组*/
这是 xcode 的新的注释,鼠标浮动时,可以显式出中文注释。
手码懒加载创建控件的步骤
1> 定义控件属性,注意:属性必须是strong的,如下:
@property (nonatomic, strong) UIImageView *icon;
2> 在属性的getter方法中实现懒加载。
使用懒加载的好处:
1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强
2> 每个控件的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合
按钮的状态
normal(普通状态) 默认情况 对应的枚举常量:UIControlStateNormal highlighted(高亮状态) 按钮被按下去的时候(手指还未松开) 对应的枚举常量:UIControlStateHighlighted disabled(失效状态,不可用状态) 如果enabled属性为NO,就是处于disable状态,代表按钮不可以被点击 对应的枚举常量:UIControlStateDisabled使用Plist文件重构本项目代码:
目的:将数据与代码分离(类似 java 里的 xml 文件写数据,数据和代码分离)
之前的代码,尤其是字典那部分,还是处理的不好,显得太耦合。需要把数据和代码分离,这里学习属性列表文件,property list
新建file

本地文件,也可以网络上解析 xml 文件

这样,只需要修改对应的 xml 文件即可,不用再打开代码,修改代码
//控件懒加载
//不需要每次都在 viewdidload 里实例化数组,只要在需要的时候实例化即可
- (NSArray *)imageList
{
//只有第一次调用imageList 的 getter 方法的时候,如果为空,那么再实例化并建立数组,其他时候,直接返回成员变量
if (_imageList == nil) {
//bundle 包的概念 只读
NSString *path = [[NSBundle mainBundle] pathForResource:@"imageDate" ofType:@".plist"];
NSLog(@"%@", path);
//File 表示从完整路径查找文件
_imageList = [NSArray arrayWithContentsOfFile:path];
}
return _imageList;
}
小结:
1、将数据与代码分离,Plist 文件的加载方法:
直接将数据直接写在代码里面,不是一种合理的做法。如果数据经常改,就要经常翻开对应的代码进行修改,造成代码扩展性低,因此,可以考虑将经常变的数据放在文件中进行存储,程序启动后从文件中读取最新的数据。如果要变动数据,直接修改数据文件即可,不用修改代码。 一般可以使用属性列表文件存储NSArray或者NSDictionary之类的数据,这种属性列表文件的扩展名是plist,因此也成为“Plist文件”NSString *path = [[NSBundle mainBundle] pathForResource:@"ImageData" ofType:@"plist"];
_imageList = [NSArray arrayWithContentsOfFile:path];
提示:通常在方法中出现File字眼,通常需要传递文件的全路径作为参数,如下全路径:
/Users/dashuai/Library/Developer/CoreSimulator/Devices/83C611C9-DE98-4D02-BC64-D31C0403766E/data/Containers/Bundle/application/E04713CF-A9D4-49D1-A934-B4093BCE5B3C/图片浏览.app/imageDate.plist
2、要想让UILabel自动换行,设置Lines为0即可。
3、UIButton和UIImageView
相同点 都能显示图片 不同点 UIButton默认情况就能监听点击事件,而UIImageView默认情况下不能 UIButton可以在不同状态下显示不同的图片 UIButton既能显示文字,又能显示图片 如何选择 UIButton:需要显示图片,点击图片后需要做一些特定的操作 UIImageView:仅仅需要显示图片,点击图片后不需要做任何事情 NSArray和NSDictionary的使用 当图片内容非常多时,“根据index来设置内容”的代码就不具备扩展性,要经常改动,为了改变现状,可以考虑将图片数据保存到一个数组中,数组中有序地放着很多字典,一个字典代表一张图片数据,包含了图片名、图片描述@property (strong, nonatomic) NSArray *images;
由于只需要初始化一次图片数据,因此放在get方法中初始化,将属性放在get方法中初始化的方式,称为“懒加载”\”延迟加载”
/**设置一个图像的数组*/
这是 xcode 的新的注释,鼠标浮动时,可以显式出中文注释。
手码懒加载创建控件的步骤
1> 定义控件属性,注意:属性必须是strong的,如下:
@property (nonatomic, strong) UIImageView *icon;
2> 在属性的getter方法中实现懒加载。
使用懒加载的好处:
1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强
2> 每个控件的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合
按钮的状态
normal(普通状态) 默认情况 对应的枚举常量:UIControlStateNormal highlighted(高亮状态) 按钮被按下去的时候(手指还未松开) 对应的枚举常量:UIControlStateHighlighted disabled(失效状态,不可用状态) 如果enabled属性为NO,就是处于disable状态,代表按钮不可以被点击 对应的枚举常量:UIControlStateDisabled