码迷,mamicode.com
首页 > 其他好文 > 详细

UIView之基础控件综合事例

时间:2015-11-26 00:59:05      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

九宫格算法实现及优化

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之基础控件综合事例

标签:

原文地址:http://www.cnblogs.com/zhoudaquan/p/4996275.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!