九宫格算法实现及优化

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. ajax同步,异步

    传输数据 同步:第一条传过去,对方接收到反馈以后,再传第二条; 异步:第一条传过去,不管对方有没有收到,继续传第二条. ajax(默认异步 async:true) 同步:执行完ajax内部代码,才执行 ...

  2. FileReader 基本介绍

    转自:http://blog.csdn.net/zk437092645/article/details/8745647 用来把文件读入内存,并且读取文件中的数据.FileReader接口提供了一个异步 ...

  3. Spring入门学习(一)

    SpringMVC基础平台补充(2016.03.03) 如果想要开发SpringMVC,那么前期依次安装好:JDK(jdk-8u74-windows-x64,安装后配置环境变量JAVA_HOME和CL ...

  4. Servlet Filter 1

    1.Filter简介 )Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图 ...

  5. linux 解压,源码包

    从网络上下载到的源码包, 最常见的是 .tar.gz 包, 还有一部分是 .tar.bz2包   要解压很简单 :   .tar.gz     格式解压为          tar   -zxvf   ...

  6. LeetCode "Minimum Height Tree" !!

    Simple data structure but not that easy to figure out.. MHT -> balanced tree.https://leetcode.com ...

  7. 安卓集成发布详解(二)gradle

    转自:http://frank-zhu.github.io/android/2015/06/15/android-release_app_build_gradle/ 安卓集成发布详解(二) 15 Ju ...

  8. php返回状态200或者300的写法

    header("HTTP/1.0 200 OK"); phpinfo(); header("HTTP/1.0 300 OK"); phpinfo();

  9. Django数据库操作

    刚学到Django的数据库操作,把它记录下来,方便以后查看: 在Django中定义数据库表,并使用Django提供的方法来对数据库进行操作(增.删.改.查) 1.定义3个数据库表: class Gro ...

  10. 黄聪:如何添加360浏览器(chrome)添加JavaScript例外,禁止网站加载JS

    注意:通配符两侧的[]不能省略