UIView之基础控件综合事例

九宫格算法实现及优化

2015年11月19日 星期四

23:21

1.九宫格之初实现

要求:

1.1在主界面中,点击添加按钮就能添加商品,点击删除按钮就能删除商品;

1.2在初始化界面中,添加按钮处于norma状态,删除按钮处于disable状态;

1.3当点击了添加按钮后,删除按钮此时处于normal状态;

1.4当商品满了后,添加按钮处于disable状态,删除按钮处于normal状态;

1.5当商品为空或者满了的时候给出提示语;

算法思路实现:

1.界面的实现:分析要用到的控件,此需求中,用到了一个view(主控件)和(内部的子控件)一个imageView,两个lable(显示title和hub),两个button(添加和删除按钮).

2.因为要对按钮和view实现操作,所以对其进行引用(获得对应的属性和删除添加操作).

3.导入相对应的图片.

4.在addProduct方法中:

4.1依次创建shopView(父控件),用于加载imageView和title,并添加到主控件中;

3.1.1分别创建imageView和title并设置frame加载到shopView中

4.2此时就需要考虑到加载的商品个数,所以引入商品的信息,用字典存储,并获得index.

4.3在定义frame的时候,考虑到程序中的魔鬼数字,就需要定义一些常量.

4.4加载字典中的icon和name并赋值给相对应的控件imageView和title.

4.5判断按钮的状态,并对enable属性进行相应的设置

5.在removeProduct方法中:

5.1调用[self.shopView.su‘b‘viewsubviews lastObject]removeFromSuperviews删除商品

5.2判断按钮的状态,并对enable属性进行相应的设置

2.九宫格实现之(字典)懒加载优化

懒加载:

作用:节省内存,当数据字典被使用时候才去使用.防止了在viewDidLoad的时候耗费内存和时间.

实现:首先就得在声明语句中声明一个数组用来保存字典中的数据.

步骤:

懒加载的步骤

1.定义成员变量

2.重写get方法

3.在get方法中判断,变量是否有值,如果没有值,则加载数据,如果有值,直接返回

- (NSArray *)products

{

if (_products == nil) {

_products = @[

@{@"icon" : @"liantiaobao", @"title" : @"链条包"},

@{@"icon" : @"shoutibao", @"title" : @"手提包"},

@{@"icon" : @"danjianbao", @"title" : @"单肩包"},

@{@"icon" : @"shuangjianbao", @"title" : @"双肩包"},

@{@"icon" : @"xiekuabao", @"title" : @"斜挎包"},

@{@"icon" : @"qianbao", @"title" : @"钱包"}

];

}

return _products;

}

3.九宫格实现之(plist文件)懒加载优化

plist懒加载:

  • 3.1什么是plist文件
  • 直接将数据直接写在代码里面,不是一种合理的做法。如果数据经常改,就要经常翻开对应的代码进行修改,造成代码扩展性低
  • 因此,可以考虑将经常变的数据放在文件中进行存储,程序启动后从文件中读取最新的数据。如果要变动数据,直接修改数据文件即可,不用修改代码
  • 一般可以使用属性列表文件存储NSArray或者NSDictionary之类的数据,这种“属性列表文件”的扩展名是plist,因此也称为“plist文件”
  • 3.2创建plist文件

3.3解析plist文件

  • 接下来通过代码来解析Plist文件中的数据
  • 获得Plist文件的全路径

NSBundle *bundle = [NSBundle mainBundle];

NSString *path = [bundle pathForResource:@"shops" ofType:@"plist"];

  • 加载plist文件

_shops = [NSArray arrayWithContentsOfFile:path];

3.4plist的使用注意

3.5如何使用懒加载

  • 接下来通过代码来解析Plist文件中的数据
  • 获得Plist文件的全路径

NSBundle *bundle = [NSBundle mainBundle];

NSString *path = [bundle pathForResource:@"shops" ofType:@"plist"];

  • 加载plist文件

_shops = [NSArray arrayWithContentsOfFile:path];

或者可以写成:

_shops = [NSArray arrayWithContentsOfFile:[NSBundle mainBundle]pathForResource:@"shops" ofType:@"plist"]];

4.九宫格实现之模型优化

4.1模型取代字典的好处:

  • 使用字典的坏处
  • 一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编辑器没有智能提示,需要手敲

dict[@"name"] = @"Jack";

NSString *name = dict[@"name"];

  • 手敲字符串key,key容易写错
  • Key如果写错了,编译器不会有任何警告和报错,造成设错数据或者取错数据
  • 使用模型的好处
  • 所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业
  • 模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性
  • 使用模型访问属性时,编译器会提供一系列的提示,提高编码效率

app.name = @"Jack";

NSString *name = app.name;

4.2.实现:

4.2.1.创建一个类模型,并声明相应的属性,用来取代字典,给相应的子控件赋值

4.2.2在懒加载中实现下面的方法:

// 问题:_products数组中存放的都是字典,字典在实际开发使用起来并不是方便

// 3.将字典转成模型对象

NSMutableArray *tempArray = [NSMutableArray array];

for (NSDictionary *dict in _products) {

// 3.1.创建模型对象

Product *product = [[Product alloc] init];

// 3.2.给模型对象的属性赋值

product.icon = dict[@"icon"];

product.title = dict[@"title"];

// 3.3.将模型对象放入数组中

[tempArray addObject:product];

}

_products = tempArray;

4.2.3用模型取代字典进行赋值

// 2.6.设置展示的数据

XMGProduct *product = self.products[index];

iconView.image = [UIImage imageNamed:product.icon];

titleLabel.text = product.title;

4.2.4考虑到在懒加载遍历数组的时候,每次创建XMGProduct的时候都得进行赋值,所以就在模型类中提供初始化方法,使得每次创建的模型对象都有对应的属性:

- (instancetype)initWithDict:(NSDictionary *)dict

{

if (self = [super init]) {

self.icon = dict[@"icon"];

self.title = dict[@"title"];

}

return self;

}

+ (instancetype)productWithDict:(NSDictionary *)dict

{

return [[self alloc] initWithDict:dict];

}

在懒加载时进行修改:

// 3.将字典转成模型对象

NSMutableArray *tempArray = [NSMutableArray array];

for (NSDictionary *dict in _products) {

XMGProduct *product = [XMGProduct productWithDict:dict];

// 3.2.将模型对象放入数组中

[tempArray addObject:product];

}

_products = tempArray;

}

5.九宫格实现之添加控件优化

5.1作用:

在UIController中需要每次创建一个shopView,然后添加到主控件view中,所以我们可以自定义控件来取代这种做法.

5.2控件的实现:

首先就是创建一个对应的类XMGProductView,在类中分别声明对应的属性iconView和titleLable,然后重写init类方法;因为无法在init方法中设置frame,所以就必须重写layoutSubviews方法

- (instancetype)init

{

if (self = [super init]) {

// 1.添加UIImageView对象用于显示商品的图片

UIImageView *iconView = [[UIImageView alloc] init];

[self addSubview:iconView];

_iconView = iconView;

// 2.添加UILabel对象用于显示商品的名字

UILabel *titleLabel = [[UILabel alloc] init];

titleLabel.textAlignment = NSTextAlignmentCenter;

[self addSubview:titleLabel];

_titleLabel = titleLabel;

}

return self;

}

- (void)layoutSubviews

{

//注意:必须调用super方法

[super layoutSubviews];

// 1.取出当前控件的宽度和高度

CGFloat width = self.frame.size.width;

CGFloat height = self.frame.size.height;

// 2.调整子控件的frame

self.iconView.frame = CGRectMake(0, 0, width, width);

self.titleLabel.frame = CGRectMake(0, width, width, height - width);

}

考虑到在自定义控件的时候,如果在.h文件中设置对应的属性,那么外界就能通过set和get方法进行修改,为了不让外界修改属性的值,所以必须重写对应的set方法,并统一提供接口.

#pragma mark - 实现接口的方法

- (void)setIcon:(NSString *)iconName

{

self.iconView.image = [UIImage imageNamed:iconName];

}

- (void)setTitle:(NSString *)title

{

self.titleLabel.text = title;

}

在addProduct的方法中,在创建控件并设置数据

/**************** 2.添加商品的View *****************************/

// 1.创建商品的View

XMGProductView *productView = [[XMGProductView alloc] init];

productView.frame = CGRectMake(x, y, width, height);

[self.shopCartView addSubview:productView];

// 2.设置数据

XMGProduct *product = self.products[index];

[productView setIcon:product.icon];

[productView setTitle:product.title];

考虑到为了更加的安全(不让外界了解具体的实现方法),所以又提供了对应的模型方法,只让外界知道模型

- (void)setProduct:(XMGProduct *)product

{

_product = product;

// 设置数据

self.iconView.image = [UIImage imageNamed:product.icon];

self.titleLabel.text = product.title;

}

在addProduct的方法中,在创建控件并设置数据

/********************2.添加商品的View *****************************/

// 1.创建商品的View

XMGProductView *productView = [[XMGProductView alloc] init];

productView.frame = CGRectMake(x, y, width, height);

[self.shopCartView addSubview:productView];

// 2.设置数据

productView.product = self.products[index];

6.九宫格实现之xib优化

6.1Xib和storyboard对比

  • 共同点:
  • 都用来描述软件界面
  • 都用Interface Builder工具来编辑
  • 本质都是转换成代码去创建控件
  • 不同点
  • Xib是轻量级的,用来描述局部的UI界面
  • Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系

6.2xib的加载

  • 方法1

NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"xib文件名" owner:nil options:nil]

  • 方法2

UINib *nib = [UINib nibWithNibName:@"xib文件名" bundle:nil];

NSArray *views = [nib instantiateWithOwner:nil options:nil];

6.3步骤:

6.4注意点

  • 一个控件有2种创建方式
  • 通过代码创建
  • 初始化时一定会调用initWithFrame:方法
  • 通过xib\storyboard创建
  • 初始化时不会调用initWithFrame:方法,只会调用initWithCoder:方法
  • 初始化完毕后会调用awakeFromNib方法
  • 有时候希望在控件初始化时做一些初始化操作,比如添加子控件、设置基本属性
  • 这时需要根据控件的创建方式,来选择在initWithFrame:、initWithCoder:、awakeFromNib的哪个方法中操作

xib界面的设置:

用xib取代自定义控件的.h文件

#import <UIKit/UIKit.h>

@class XMGProduct;

@interface XMGProductView : UIView

// 快速创建类方法

+ (instancetype)productView;

// 提供模型接口

@property (nonatomic, strong) XMGProduct *product;

@end

用xib取代自定义控件的.m文件

#import "XMGProductView.h"

#import "XMGProduct.h"

@interface XMGProductView ()

@property (weak, nonatomic) IBOutlet UIImageView *iconView;

@property (weak, nonatomic) IBOutlet UILabel *titleLabel;

@end

@implementation XMGProductView

+ (instancetype)productView

{

return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] firstObject];

}

- (void)setProduct:(XMGProduct *)product

{

_product = product;

// 给子控件设置数据

self.iconView.image = [UIImage imageNamed:product.icon];

self.titleLabel.text = product.title;

}

@end

在addProduct的方法中,在创建控件并设置数据

/*********************2.添加商品的View *****************************/

// 1.创建商品的View

XMGProductView *productView = [XMGProductView productView];

productView.frame = CGRectMake(x, y, width, height);

[self.shopCartView addSubview:productView];

// 2.设置数据

productView.product = self.products[index];

7.九宫格实现之提示框动画效果优化

考虑到add和remove的提示框的内容除了提示语不同外,其他的都一样,所以就把提示方法抽取出来简洁代码:

注意:hubLabel为view中的提示框的属性

- (void)showHubInfo:(NSString *)hubInfo

{

// 3.1.改变指示器上面显示的文字

self.hubLabel.text = hubInfo;

// 3.2.出现动画和消失动画

[UIView animateWithDuration:1.0 animations:^{

self.hubLabel.alpha = 1.0;

} completion:^(BOOL finished) {

[UIView animateWithDuration:1.0 delay:2.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

self.hubLabel.alpha = 0.0;

} completion:nil];

}];

}

在addProduct的方法中,调用该方法

/************** 4.购物车已满,给用户提示 *************************/

if (self.shopCartView.subviews.count == 6) {

[self showHubInfo:@"购物车已满,不要买买买啦!"];

}

在removeProduct的方法中,调用该方法

// 3.购物车已空,给用户提示

if (self.shopCartView.subviews.count == 0) {

[self showHubInfo:@"购物车已空,赶紧买买买啦!"];

}

时间: 2024-08-27 02:09:14

UIView之基础控件综合事例的相关文章

02-UI基础控件(综合)

[iOS基础控件 - 5.5] 代理设计模式 (基于”APP列表&quot;练习)

A.概述 在"[iOS基础控件 - 4.4] APP列表 进一步封装,初见MVC模式”上进一步改进,给“下载”按钮加上效果.功能 1.按钮点击后,显示为“已下载”,并且不可以再按 2.在屏幕中间弹出一个消息框,通知消息“xx已经被安装”,慢慢消失 3.消息框样式为圆角半透明 B.不使用代理模式,使用app空间组和主View之间的父子View关系 1.在主View中创建一个消息框 主View控制器:ViewController.m 1 // 创建下载成功消息框 2 CGFloat labelWid

???01-UIKIT基础控件小结

iOS开发概述 cocos体系结构,一共有四层框架,要调用不同的功能,需要使用不同的框架.前期主要学习cocos touch层的UIKit框架 iOS和android的对比 ü   iOS是基于UINX,用C语言开发的,直接与系统底层交互,性能高 ü   andorid是基于Linux,用Java语言开发,基于虚拟机运行,性能差 UI基础控件 1.    UILabel——标签 作用:显示文字 属性: text属性:是label的文字 alignment属性:对齐方式 lines属性:如果为0,

HTML 基础控件介绍

HTML 基础控件介绍 主要介绍 input.select.textarea.label.fieldset.ul.ol.li等标签 目录 1. <input>标签:主要用于收集用户信息,可根据不同的type属性值,拥有多种形式. 2. <select>标签:可创建单选或多选菜单,类似于winform的combox或listbox. 3. <textarea>标签:多行文本区域. 4. <label>标签:相当于一个展示文本框. 5. <fieldset

0821基础控件(UILabel常用属性)

一.UILabel常用属性1--实例化和设置文字 // 实例化UILabel并指定其边框 UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0.0, 210.0, 320.0, 40.0)]; // 设置label显示的文本 [label setText:@"Hello World"]; // 设置字体和字体大小 [label setFont:[UIFont fontWithName:@"Helvetica-B

0821基础控件(UIButton常用属性)

一.可以通过代码的方式创建UIButton 1.通用实例化对象方法: UIButton *button = [[UIButton alloc] initWithFrame:rect]; 2.快速实例化对象方法: UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 提示: 在OC开发中,实例化任何类型的非自定义对象,都请首先尝试一下是否存在快速定义方法.如果存在快速定义方法,就尽量不要使用init之类的方法实例

Delphi一共封装(超类化)了8种Windows基础控件和17种复杂控件

超类化源码: procedure TWinControl.CreateSubClass(var Params: TCreateParams; ControlClassName: PChar); const {CS_OWNDC标志,属于此窗口类的窗口实例都有自己的DC(称为私有DC) } {CS_CLASSDC标志,所有属于该类的窗口实例共享相同的DC(称为类DC).类DC有一些私有DC的优点,而更加节约内存} {CS_PARENTDC标志,属于这个类的窗口都使用它的父窗口的句柄.和CS_CLAS

iOS基础控件UINavigationController中的传值

iOS基础控件UINavigationController中的传值,代理传值,正向传值,反向传值 #import <UIKit/UIKit.h> //声明一个协议 @protocol SendValue<NSObject> //定义一个方法 - (void)sendBtnTitle:(NSString *)title; @end @interface FirstViewController : UIViewController // 定义代理 @property (nonatomi

[iOS基础控件 - 4.5] 猜图游戏

A.需要掌握的 1.添加图片资源(暂时认为@2x跟非@2x代表同一张图片) 2.搭建UI界面* 文本标签* 4个按钮* 中间的图片 3.设置状态栏样式 4.监听下一题按钮的点击 5.延迟加载数据* 加载plist* 字典转模型* KVC的引入 6.切换下一题的序号.图片.标题,下一题按钮的可用性 7.默认显示第1条题目 8.显示大图* 监听中间图片点击* 添加遮盖* 移动图片(注意头像图片的层级顺序)* 监听“大图按钮” 9.展示答案的个数 10.展示待选答案 11.答案处理 12.提示功能 1