UI基础
UIButton简单封装
第一步简单封装一个button按钮
/** * 创建添加按钮 * * @param image 按钮图片 * @param highImage 高亮状态下的图片 * @param disableImage 禁用状态下的图片 * @param frame 位置和尺寸 * @param action 监听按钮点击事件 */ - (void)addButtonWithImage:(NSString *) image highImage:(NSString *)highImage disableImage:(NSString *)disableImage frame:(CGRect)frame action:(SEL)action { // 创建按钮 UIButton * btn = [[UIButton alloc] init]; // 设置背景图片 [btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal]; [btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted]; [btn setBackgroundImage:[UIImage imageNamed:disableImage] forState:UIControlStateDisabled]; // 设置尺寸 btn.frame = frame; // 监听按钮点击事件 [btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; // 添加按钮 [self.view addSubview:btn]; }
在viewDidLoad中调用
- (void)viewDidLoad {
[super viewDidLoad];
[self addButtonWithImage:@"add" highImage:@"add_highlighted" disableImage:@"add_disabled" frame:CGRectMake(30, 30, 50, 50) action:@selector(add)];
[self addButtonWithImage:@"remove" highImage:@"remove_highlighted" disableImage:@"remove_disabled" frame:CGRectMake(270, 30, 50, 50) action:@selector(remove)];
}
结果如图所示 两张简单的图片展示,但是主要是用了一个最简单的封装,方便多次调用,避免重复造轮子。
- 实现button中两个监听方法
#pragma mark 添加
- (void)add {
NSLog(@"add---");
}
#pragma mark 删除
- (void)remove {
NSLog(@"remove--");
}
这样第一个简单的UI程序就写出来了
方法总结 - UIButton中常用的方法
[btn setBackgroundImage:<#(nullable UIImage *)#> forState:<#(UIControlState)#>]; // 设置button上背景图片,有多中不同的状态
[btn setTitle:<#(nullable NSString *)#> forState:<#(UIControlState)#>]; // 设置button上的字体 ,有多种不同的状态,默认文字是在右边,图片在左边
[btn setImage:<#(nullable UIImage *)#> forState:<#(UIControlState)#>]; // 设置button上的图片,哟多种不同的状态,默认图片在左边
UIButton再次封装
- 添加add方法
- (void)add {
// 添加图片
UIImageView *iconView = [[UIImageView alloc] init];
iconView.image = [UIImage imageNamed:@"danjianbao"];
iconView.frame = CGRectMake(0, 0, 50, 70);
[self.shopsView addSubview:iconView];
// 添加文字
UILabel *label = [[UILabel alloc] init];
label.text = @"单肩包";
label.frame = CGRectMake(0, 50, 50, 20);
label.font = [UIFont systemFontOfSize:10];
label.textAlignment = NSTextAlignmentCenter;
[self.shopsView addSubview:label];
}
点击add按钮之后出现的效果 此时无论点击多少次都只会有这个一个效果,因为我们已经在add方法内部写死了他的位置和尺寸
我们需要重新改进add方法 解决思路为,每次点击添加之后计算位置,假设每行有4个商品,每次点击商品数量+1 , 每次点击添加之后当前商品的索引为其控件中的所有子控件 例如:当前shopsView中有5件商品,那么点击之后的商品数量应该为6个,其商品下表为index=5,根据这个思路我们可以继续下面的步骤了(注:每次商品跟商品名称同时出现,我们可以将之封装在同一个view上)
- (void)add {
// 商品的大小
CGFloat shopW = 50;
CGFloat shopH = 70;
// 每行商品有5个
int cols = 5;
// 每行商品间距
CGFloat rowMargin = 10;
// 每列商品间距
CGFloat colMargin = (self.shopsView.bounds.size.width - shopW * cols)/(cols - 1);
// 单一商品容器
UIView * shopView = [[UIView alloc] init];
// 商品索引
NSUInteger index = self.shopsView.subviews.count;
// 商品索引x值
NSUInteger shopIndexX = index % cols;
// 商品索引y值
NSUInteger shopIndexY = index / cols;
//商品x,y坐标
CGFloat shopX = shopIndexX * (colMargin + shopW);
CGFloat shopY = shopIndexY * (rowMargin + shopH);
// 设置商品容器frame
shopView.frame = CGRectMake(shopX, shopY, shopW, shopH);
[self.shopsView addSubview:shopView];
// 添加图片
UIImageView *iconView = [[UIImageView alloc] init];
iconView.image = [UIImage imageNamed:@"danjianbao"];
iconView.frame = CGRectMake(0, 0, shopW, shopH);
[shopView addSubview:iconView];
// 添加文字
UILabel *label = [[UILabel alloc] init];
label.text = @"单肩包";
label.frame = CGRectMake(0, shopW, shopW, shopH - shopW);
label.font = [UIFont systemFontOfSize:10];
label.textAlignment = NSTextAlignmentCenter;
[shopView addSubview:label];
}
注意:其中商品容器 shopView添加到self.shopsView上这一步骤需要在计算商品索引之后进行,否则会出现添加商品第一位空缺的情况。
UIButton封装数据存储
思考:每次我使用在shopsView中放数据,都需要重新设置一个UIImageView以及一个UILabel.我们可以将之封装到一个单独的shopView中,然后导入shopView 头文件来使用它。而且一般我们使用这些数据的时候都是从服务器下载,一般下载的格式都是字典形式。
我们可以改进代码
//
// ViewController.m
// 01-UI基础
//
// Created by 王加祥 on 16/4/10.
// Copyright © 2016年 Wangjiaxiang. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
/** 图片仓库 */
@property (nonatomic,strong) UIView * shopsView;
/** 添加按钮 */
@property (nonatomic,weak) UIButton * addBtn;
/** 删除按钮 */
@property (nonatomic,weak) UIButton * removeBtn;
/** 商品数据 */
@property (nonatomic,strong) NSArray * shops;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 数据
self.shops = @[
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
},
@{
@"icon":@"liantiaobao",
@"name":@"聊天包"
},
@{
@"icon":@"shubao",
@"name":@"包"
},
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
},
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
},
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
}
];
[self.view addSubview:self.shopsView];
self.addBtn = [self addButtonWithImage:@"add" highImage:@"add_highlighted" disableImage:@"add_disabled" frame:CGRectMake(30, 30, 50, 50) action:@selector(add)];
self.removeBtn = [self addButtonWithImage:@"remove" highImage:@"remove_highlighted" disableImage:@"remove_disabled" frame:CGRectMake(270, 30, 50, 50) action:@selector(remove)];
self.removeBtn.enabled = NO; // 刚进来的时候商品为空,此控件为禁用状态、
}
/**
* 创建添加按钮
*
* @param image 按钮图片
* @param highImage 高亮状态下的图片
* @param disableImage 禁用状态下的图片
* @param frame 位置和尺寸
* @param action 监听按钮点击事件
*/
- (UIButton *)addButtonWithImage:(NSString *) image highImage:(NSString *)highImage disableImage:(NSString *)disableImage frame:(CGRect)frame action:(SEL)action {
// 创建按钮
UIButton * btn = [[UIButton alloc] init];
// 设置背景图片
[btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[UIImage imageNamed:disableImage] forState:UIControlStateDisabled];
// 设置尺寸
btn.frame = frame;
// 监听按钮点击事件
[btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
// 添加按钮
[self.view addSubview:btn];
return btn;
}
#pragma mark 添加
- (void)add {
// 商品的大小
CGFloat shopW = 50;
CGFloat shopH = 70;
// 每行商品有5个
int cols = 5;
// 每行商品间距
CGFloat rowMargin = 10;
// 每列商品间距
CGFloat colMargin = (self.shopsView.bounds.size.width - shopW * cols)/(cols - 1);
// 单一商品容器
UIView * shopView = [[UIView alloc] init];
// 商品索引
NSUInteger index = self.shopsView.subviews.count;
// 商品索引x值
NSUInteger shopIndexX = index % cols;
// 商品索引y值
NSUInteger shopIndexY = index / cols;
//商品x,y坐标
CGFloat shopX = shopIndexX * (colMargin + shopW);
CGFloat shopY = shopIndexY * (rowMargin + shopH);
// 设置商品容器frame
shopView.frame = CGRectMake(shopX, shopY, shopW, shopH);
[self.shopsView addSubview:shopView];
// 添加图片
UIImageView *iconView = [[UIImageView alloc] init];
iconView.image = [UIImage imageNamed:self.shops[index][@"icon"]];
iconView.frame = CGRectMake(0, 0, shopW, shopH);
[shopView addSubview:iconView];
// 添加文字
UILabel *label = [[UILabel alloc] init];
label.text = self.shops[index][@"name"];
label.frame = CGRectMake(0, shopW, shopW, shopH - shopW);
label.font = [UIFont systemFontOfSize:10];
label.textAlignment = NSTextAlignmentCenter;
[shopView addSubview:label];
[self btnState];
}
#pragma mark 删除
- (void)remove {
[self.shopsView.subviews.lastObject removeFromSuperview];
[self btnState];
}
#pragma mark - layzingLoad
- (UIView *)shopsView {
if (_shopsView == nil) {
_shopsView = [[UIView alloc] init];
_shopsView.frame = CGRectMake(10, 100, 400, 400);
}
return _shopsView;
}
#pragma mark 按钮状态
- (void)btnState {
self.removeBtn.enabled = (self.shopsView.subviews.count != 0);
self.addBtn.enabled = (self.shopsView.subviews.count != self.shops.count);
}
@end
说明
- 首先将数据抽离出来,在viewDidLoad中加载,这样就只加载一次,不用每次都要加载。
- 将封装的button中接口返回button用来设置每次每个不同状态下的button的状态
- 设置按钮状态 当self.shopsView.subviews.count != 0的时候此时删除按钮是禁用状态 同理可设定添加按钮
- 将设置按钮状态抽离出一个单独的方法 改进之后的效果如图
设置提示按钮
当商品添加结束或者是商品完全删除,我们友好的界面应该是给用户提示,我们可以直接设置label来给用户提示,直接上代码
//
// ViewController.m
// 01-UI基础
//
// Created by 王加祥 on 16/4/10.
// Copyright © 2016年 Wangjiaxiang. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
/** 图片仓库 */
@property (nonatomic,strong) UIView * shopsView;
/** 添加按钮 */
@property (nonatomic,weak) UIButton * addBtn;
/** 删除按钮 */
@property (nonatomic,weak) UIButton * removeBtn;
/** 商品数据 */
@property (nonatomic,strong) NSArray * shops;
/** HUD */
@property (nonatomic,strong) UILabel * label;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 数据
self.shops = @[
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
},
@{
@"icon":@"liantiaobao",
@"name":@"聊天包"
},
@{
@"icon":@"shubao",
@"name":@"包"
},
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
},
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
},
@{
@"icon":@"danjianbao",
@"name":@"单肩包"
}
];
[self.view addSubview:self.shopsView];
[self.view addSubview:self.label];
self.label.alpha = 0;
self.addBtn = [self addButtonWithImage:@"add" highImage:@"add_highlighted" disableImage:@"add_disabled" frame:CGRectMake(30, 30, 50, 50) action:@selector(add)];
self.removeBtn = [self addButtonWithImage:@"remove" highImage:@"remove_highlighted" disableImage:@"remove_disabled" frame:CGRectMake(270, 30, 50, 50) action:@selector(remove)];
self.removeBtn.enabled = NO;
}
/**
* 创建添加按钮
*
* @param image 按钮图片
* @param highImage 高亮状态下的图片
* @param disableImage 禁用状态下的图片
* @param frame 位置和尺寸
* @param action 监听按钮点击事件
*/
- (UIButton *)addButtonWithImage:(NSString *) image highImage:(NSString *)highImage disableImage:(NSString *)disableImage frame:(CGRect)frame action:(SEL)action {
// 创建按钮
UIButton * btn = [[UIButton alloc] init];
// 设置背景图片
[btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[UIImage imageNamed:disableImage] forState:UIControlStateDisabled];
// 设置尺寸
btn.frame = frame;
// 监听按钮点击事件
[btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
// 添加按钮
[self.view addSubview:btn];
return btn;
}
#pragma mark 添加
- (void)add {
// 商品的大小
CGFloat shopW = 50;
CGFloat shopH = 70;
// 每行商品有5个
int cols = 5;
// 每行商品间距
CGFloat rowMargin = 10;
// 每列商品间距
CGFloat colMargin = (self.shopsView.bounds.size.width - shopW * cols)/(cols - 1);
// 单一商品容器
UIView * shopView = [[UIView alloc] init];
// 商品索引
NSUInteger index = self.shopsView.subviews.count;
// 商品索引x值
NSUInteger shopIndexX = index % cols;
// 商品索引y值
NSUInteger shopIndexY = index / cols;
//商品x,y坐标
CGFloat shopX = shopIndexX * (colMargin + shopW);
CGFloat shopY = shopIndexY * (rowMargin + shopH);
// 设置商品容器frame
shopView.frame = CGRectMake(shopX, shopY, shopW, shopH);
[self.shopsView addSubview:shopView];
// 添加图片
UIImageView *iconView = [[UIImageView alloc] init];
iconView.image = [UIImage imageNamed:self.shops[index][@"icon"]];
iconView.frame = CGRectMake(0, 0, shopW, shopH);
[shopView addSubview:iconView];
// 添加文字
UILabel *label = [[UILabel alloc] init];
label.text = self.shops[index][@"name"];
label.frame = CGRectMake(0, shopW, shopW, shopH - shopW);
label.font = [UIFont systemFontOfSize:10];
label.textAlignment = NSTextAlignmentCenter;
[shopView addSubview:label];
[self btnState];
}
#pragma mark 删除
- (void)remove {
[self.shopsView.subviews.lastObject removeFromSuperview];
[self btnState];
}
#pragma mark - layzingLoad
- (UIView *)shopsView {
if (_shopsView == nil) {
_shopsView = [[UIView alloc] init];
_shopsView.frame = CGRectMake(10, 100, 400, 400);
}
return _shopsView;
}
- (UILabel *)label {
if (_label == nil) {
_label = [[UILabel alloc] init];
_label.frame = CGRectMake(0, 300, 400, 20);
_label.textAlignment = NSTextAlignmentCenter;
}
return _label;
}
#pragma mark 按钮状态
- (void)btnState {
self.removeBtn.enabled = (self.shopsView.subviews.count != 0);
self.addBtn.enabled = (self.shopsView.subviews.count != self.shops.count);
if (self.removeBtn.enabled == NO) {
self.label.alpha = 1;
self.label.text = @"没有东西可删除了";
/**
* 隐藏HUD
* @selector(hideHUD) 调用方法å
* withObject : 传入参数
* afterDelay :多长时间之后调用
*/
// [self performSelector:@selector(hideHUD) withObject:nil afterDelay:1.5];
/** 多线程方法调用 */
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//
// self.label.alpha = 0.0;
// });
/**
* 定时器调用方法
*/
[NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(hideHUD) userInfo:nil repeats:NO];
} else if (self.addBtn.enabled == NO) {
self.label.alpha = 1;
self.label.text = @"没有东西可添加了";
[self performSelector:@selector(hideHUD) withObject:nil afterDelay:1.5];
}
}
/**
* 隐藏HUD
*/
- (void)hideHUD {
self.label.alpha = 0.0;
}
@end
- 首先在self.view 中添加一个label,我们用懒加载的方式来实现
- 半透明HUD,将背景颜色设置为半透明
- 设置label的显示可以有两种方法,一种是设置透明度,一种是直接隐藏,还有一种可以直接删除(在本工程中我们不提倡)
- 设置label提示之后需要隐藏 有三种方法
[self performSelector:@selector(hideHUD) withObject:nil afterDelay:1.5];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.label.alpha = 0.0; });
[NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(hideHUD) userInfo:nil repeats:NO];
- 项目中添加的所有资源都会在主资源包中
- 项目中有出现一个类无法顶底的错误,可能是没有加载到资源包中。需要在target Build Phases 中Compile Sources 检查是否加入
封装模型
新建一个类,继承NSObject,模型累不结构改变的时候外部调用方法不需要改变
- 新建Shop类
//
// Shop.h
// 01-UI基础
//
// Created by 王加祥 on 16/4/10.
// Copyright © 2016年 Wangjiaxiang. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Shop : NSObject
/** 商品图片 */
@property (nonatomic,strong) NSString * icon;
/** 商品名称 */
@property (nonatomic,strong) NSString * name;
/** 类方法:直接将字典传入参数 */
+ (instancetype)shopWithDictionary:(NSDictionary *)dict;
/** 对象方法:直接将字典传入参数 */
- (instancetype)initWithDictionary:(NSDictionary *)dict;
@end
// Shop.m
// 01-UI基础
//
// Created by 王加祥 on 16/4/10.
// Copyright © 2016年 Wangjiaxiang. All rights reserved.
//
#import "Shop.h"
@implementation Shop
+ (instancetype)shopWithDictionary:(NSDictionary *)dict {
return [[self alloc] initWithDictionary:dict];
}
- (instancetype)initWithDictionary:(NSDictionary *)dict {
if (self = [super init]) {
self.name = dict[@"name"];
self.icon = dict[@"icon"];
}
return self;
}
@end
使用方法就是将字典直接转为模型。
改进add方法
- (void)add {
// 商品的大小
CGFloat shopW = 50;
CGFloat shopH = 70;
// 每行商品有5个
int cols = 5;
// 每行商品间距
CGFloat rowMargin = 10;
// 每列商品间距
CGFloat colMargin = (self.shopsView.bounds.size.width - shopW * cols)/(cols - 1);
// 单一商品容器
UIView * shopView = [[UIView alloc] init];
// 商品索引
NSUInteger index = self.shopsView.subviews.count;
// 商品索引x值
NSUInteger shopIndexX = index % cols;
// 商品索引y值
NSUInteger shopIndexY = index / cols;
//商品x,y坐标
CGFloat shopX = shopIndexX * (colMargin + shopW);
CGFloat shopY = shopIndexY * (rowMargin + shopH);
// 设置商品容器frame
shopView.frame = CGRectMake(shopX, shopY, shopW, shopH);
[self.shopsView addSubview:shopView];
Shop * shop = self.shops[index];
// 添加图片
UIImageView *iconView = [[UIImageView alloc] init];
iconView.image = [UIImage imageNamed:shop.icon];
iconView.frame = CGRectMake(0, 0, shopW, shopH);
[shopView addSubview:iconView];
// 添加文字
UILabel *label = [[UILabel alloc] init];
label.text = shop.name;
label.frame = CGRectMake(0, shopW, shopW, shopH - shopW);
label.font = [UIFont systemFontOfSize:10];
label.textAlignment = NSTextAlignmentCenter;
[shopView addSubview:label];
[self btnState];
}
重写懒加载数组方法
- (NSArray *)shops {
if (_shops == nil) {
// 加载数据
NSString * file = [[NSBundle mainBundle] pathForResource:@"shops" ofType:@"plist"];
_shops = [NSArray arrayWithContentsOfFile:file];
NSMutableArray * shopArray = [NSMutableArray array];
for (NSDictionary * dict in _shops) {
Shop * shop = [Shop shopWithDictionary:dict];
[shopArray addObject:shop];
}
_shops = shopArray;
}
return _shops;
}
这样整个项目就暂时封装完成