九宫格算法实现及优化

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:@"购物车已空,赶紧买买买啦!"];

}

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

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

    A.概述      在"[iOS基础控件 - 4.4] APP列表 进一步封装,初见MVC模式”上进一步改进,给“下载”按钮加上效果.功能      1.按钮点击后,显示为“已下载”,并且不 ...

  2. React Native环境搭建以及几个基础控件的使用

    之前写了几篇博客,但是没有从最基础的开始写,现在想了想感觉不太合适,所以现在把基础的一些东西给补上,也算是我从零开始学习RN的经验吧! 一.环境搭建 首先声明一下,本人现在用的编辑器是SublimeT ...

  3. UIView上的控件使用push方法跳转

    有时候在项目中,为了保持前后页面的推进方式跳转方式一致,会在通过UIview上的控件跳到另一个Controller上,所以,这时候就需要用到这种方式了,当然,present方法可以实现跳转但是样式可能 ...

  4. Cocos2d-JS项目之二:studio基础控件的使用

    在studio里把几个基础控件往场景文件一拖,然后导出json格式的资源文件 逻辑代码如下: var HelloWorldLayer = cc.Layer.extend({ sprite:null, ...

  5. [iOS基础控件 - 6.6] 展示团购数据 自定义TableViewCell

    A.需求 1.头部广告 2.自定义cell:含有图片.名称.购买数量.价格 3.使用xib设计自定义cell,自定义cell继承自UITableViewCell 4.尾部“加载更多按钮”,以及其被点击 ...

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

    A.需要掌握的 1.添加图片资源(暂时认为@2x跟非@2x代表同一张图片) 2.搭建UI界面* 文本标签* 4个按钮* 中间的图片 3.设置状态栏样式 4.监听下一题按钮的点击 5.延迟加载数据* 加 ...

  7. [iOS基础控件 - 1] UI概念

    A. UIView 1.概念      属于UIKit框架      屏幕上能看得见摸得着的东西就是UIView,比如屏幕上的按钮.文字.图片      翻译为:视图/控件/组件      UIBut ...

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

    超类化源码: procedure TWinControl.CreateSubClass(var Params: TCreateParams; ControlClassName: PChar); con ...

  9. Cocos2d-JS studio基础控件的使用

    在studio里把几个基础控件往场景文件一拖,然后导出json格式的资源文件 逻辑代码如下: 1 var HelloWorldLayer = cc.Layer.extend({ 2 sprite:nu ...

随机推荐

  1. HDP2.4安装(二):Centos7配置

    Centos7 Minimal Install 安装完成后是不支持上网的,并且大部分常用的软件也未安装,首先要解决的问题就是网络配置.当网络配通后,即可通过Xshell或其它工具来远程进行操作与管理, ...

  2. ABP系列文章总目录:

    转自:http://www.cnblogs.com/mienreal/p/4528470.html 1.ABP总体介绍 2.ASP.NET Boilerplate入门 3.ABP分层架构 4.ABP模 ...

  3. Struts2 - Study 1

    领略下传说中的Struts2,写了个小例子,有点意思.比起.net中的MVC有意思的在于它是你自己一步步去配置实现,想怎么搞就怎么搞,.net的MVC,它干了什么事你完全不知,只不过知道怎么用而已. ...

  4. 【jmeter】WebSerivice测试

    WebSerivice测试计划的取样器有两种方式:HTTP请求.SOAP/XML-RPC Request. 1. 测试计划 启动JMeter,点击测试计划节点上,重命名测试计划:WebserviceT ...

  5. android学习笔记28——Activity生命周期

    Activity生命周期 Activity的活动状态由android已Activity栈的形式管理,当前活动的Activity位于栈顶.随着不同应用的运行,每个Activity都有可能从活动状态转入非 ...

  6. Java的外部类和内部类+静态变量和非静态变量的组合关系

    看的李刚<疯狂java讲义>,里面讲内部类的地方感觉有点散而且不全,看完之后还是不十分清楚到底怎么用,于是自己写了个程序测试了一下.看如下代码,即可知道外部类和内部类+静态成员和非静态成员 ...

  7. 黄聪:get_posts 函数 | wordpress

    get_posts 函数,简单的来讲是 get_post 的复数新形势,但因为是文章多篇提取,所以使用方法上却略有不同,支持众多参数选择需要提取的文章,在 CMS 主题中经常被用到,当然如果你对 Wo ...

  8. room-views-用窗口颜色清除背景(Clear Background with Window Colour)选项

    这个选项是默认开启的,它的作用是在游戏每一帧绘制以前,都用一个颜色打底(覆盖整个游戏场景包括背景,从而实现背景清除),然后在这个基础上再画背景.场景等等. 如果关闭,则在游戏每一帧以前绘制背景(绘制背 ...

  9. PLSQL_Oracle Logon Trigger的建立

    20150609 Created By BaoXinjian

  10. CF109 C. Lucky Tree 并查集

    Petya loves lucky numbers. We all know that lucky numbers are the positive integers whose decimal re ...