我会采取理论与代码分离的方式来写,在代码中用注释来说明步骤
设计的主要技术
这里值的九宫格并不局限于传统意义上的3x3格子,这个计算是能够扩展到nxn格子的计算.
在这里主要是拿到商品控件左上角的点。比如第0个商品的点就是(0.0)
在这里假设每个商品的宽高都是固定的(实际也是这样的)
每个商品的frame的x值等于商品的宽度加上间距再乘以列号
每列间距等于整个柜子的宽度减去总商品的宽度再除以每列商品个数减1
/************** 一些常用的变量 begin **************/
// 每一行的列数
NSUInteger colsPerRow = 3;
// 获得当前商品的索引
NSUInteger index = self.shopsView.subviews.count;
// 商品宽度
CGFloat shopW = 70;
// 商品高度
CGFloat shopH = 90;
/************** 一些常用的变量 end **************/
/************** 计算X值 begin **************/
// 求出列号
NSUInteger col = index % colsPerRow;
// 每一列之间的间距
CGFloat xMargin = (self.shopsView.frame.size.width - colsPerRow * shopW) / (colsPerRow - 1);
// 商品X
CGFloat shopX = (shopW + xMargin) * col;
/************** 计算X值 end **************/
/************** 计算Y值 begin **************/
// 求出行号
NSUInteger row = index / colsPerRow;
// 每一行之间的间距
CGFloat yMargin = 20;
// 商品Y
CGFloat shopY = (shopH + yMargin) * row;
/************** 计算Y值 end **************/
initWithFrame:
方法中添加子控件(init方法内部会自动调用initWithFrame:方法)layoutSubviews
方法中设置frame等数据,即布局子控件(注:这里一定要调用super的layoutSubviews
方法)- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
......
}
return self;
}
/***********************************************/
/**
* 当前控件的frame发生改变的时候就会调用
* 这个方法专门用来布局子控件,设置子控件的frame
*/
- (void)layoutSubviews
{
// 一定要调用super方法
[super layoutSubviews];
......
}
/***********************************************/
- (void)setShop:(XMGShop *)shop
{
_shop = shop;
......
}
懒加载也叫延时加载,即在第一次用的时候在去加载。下一次再想用的时候也不用不加载了,判断一下就ok了。懒加载广泛用于IOS开发中,并且是苹果官方非常推荐的一种方式。
特点:
本质是重写了get方法
代码示例
@property (nonatomic, strong) NSArray *shops;
//.....................................//
- (NSArray *)shops
{
if (_shops == nil) {_shops = 。。。。}
return _shops;
}
return _shops;
}
好处:
1、在写字典的时候,很容易将key什么的写错了,但是xcode不会好心报错的
2、逻辑分开,符合MVC原则
3、让代码易于维护
4、提高复用效率
5、。。。。
// Shop.h
#import <Foundation/Foundation.h>
@interface Shop : NSObject
@property(nonatomic,strong)NSString *name;
@property(nonatomic,strong)NSString *icon;
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)shopWithDict:(NSDictionary*)dict;
@end
/*-------------------------------------------------------*/
// Shop.m
#import "Shop.h"
@implementation Shop
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self =[super init]) {
self.name = dict[@"name"];
self.icon = dict[@"icon"];
}
return self;
}
+ (instancetype)shopWithDict:(NSDictionary*)dict
{
return [[self alloc] initWithDict:dict];
}
@end
#import "ViewController.h"
#import "LGShop.h"
#import "LGShopView.h"
@interface ViewController ()
//商品
@property (nonatomic, strong) NSArray *shops;
//商品柜子
@property (weak, nonatomic) IBOutlet UIView *shopsView;
//添加按钮
@property (weak, nonatomic) IBOutlet UIButton *addButton;
//移除按钮
@property (weak, nonatomic) IBOutlet UIButton *removeButton;
- (IBAction)add;
- (IBAction)remove;
@end
@implementation ViewController
#pragma mark - lazy
- (NSArray *)shops
{
if (!_shops) {
//获取plist文件路径
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"shops.plist" ofType:nil];
//根据路径加载
NSArray *shopsArray = [NSArray arrayWithContentsOfFile:filePath];
//创建一个临时可变数值用来装商品
NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:shopsArray.count];
//遍历每一个字典,将其转换为模型
for (NSDictionary *dict in shopsArray) {
LGShop *shop = [LGShop shopWithDict:dict];
[tempArray addObject:shop];
}
_shops = [tempArray copy];
}
return _shops;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.removeButton.enabled = NO;
}
#pragma mark - 当点击添加商品的时候调用
- (IBAction)add {
//九宫格计算,主要计算每个商品的x和y
//每一行的列数
int colsPerRow = 4;
//商品索引
NSUInteger index = self.shopsView.subviews.count;
//商品的高和宽
CGFloat shopH = 90;
CGFloat shopW = 70;
//商品柜的宽高
// CGFloat shopViewH = self.shopsView.frame.size.height;
CGFloat shopViewW = self.shopsView.bounds.size.width;
//求x
//列号
int cols = index%colsPerRow;
//列间距
CGFloat maginX = (shopViewW - shopW * colsPerRow)/(colsPerRow - 1);
//x值
CGFloat shopX = (shopW + maginX) * cols;
//求y
//行号
unsigned long rows = index/ colsPerRow;
//行间距等于列间距
CGFloat maginY = maginX;
//y值
CGFloat shopY = 20 +(shopH + maginY) * rows;
//商品父控件
LGShopView *shopView = [[LGShopView alloc] init];
shopView.frame = CGRectMake(shopX, shopY, shopW, shopH);
[self.shopsView addSubview:shopView];
//设置数据
shopView.shop = self.shops[index];
//当添加了仓库中所有的商品后,不能再添加
self.removeButton.enabled = YES;
self.addButton.enabled = (self.shops.count>self.shopsView.subviews.count);
}
#pragma mark - 当点击删除商品的时候调用
- (IBAction)remove {
//移除最后一个添加的商品
[self.shopsView.subviews.lastObject removeFromSuperview];
//当移除完以后不能再移除
self.addButton.enabled =YES;
self.removeButton.enabled = (self.shopsView.subviews.count>0);
}
@end
#import "LGShop.h"
@implementation LGShop
//对类方法和对象方法的实现
+ (instancetype)shopWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
//1.老实转法
self.name = dict[@"name"];
self.icon = dict[@"icon"];
/*
//2.kvc转法 下面这一句是使用的KVC
[self setValuesForKeysWithDictionary:dict];
*/
}
return self;
}
@end
@interface LGShopView ()
@property (nonatomic, weak) UIImageView *imageView;
@property (nonatomic, weak) UILabel *nameLabel;
@end
@implementation LGShopView
(nonnull instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
//添加图片空间
UIImageView *shopImageView = [[UIImageView alloc] init];
[self addSubview:shopImageView];
self.imageView = shopImageView;
//添加文字控件
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.textAlignment = NSTextAlignmentCenter;
self.nameLabel = nameLabel;
[self addSubview:nameLabel];
}
return self;
}
(void)layoutSubviews
{
[super layoutSubviews];
CGFloat shopW = self.frame.size.width;
CGFloat shopH = self.frame.size.height;
self.imageView.frame = CGRectMake(0, 0, shopW, shopW);
self.nameLabel.frame = CGRectMake(0, shopW, shopW, shopH - shopW);
}
//重写set方法为子控件赋值
-(void)setShop:(LGShop *)shop
{
_shop =shop;
self.imageView.image = [UIImage imageNamed:shop.icon];
self.nameLabel.text = shop.name;
}
@end
“`
- 代码仓库有全部代码:
- https://github.com/LGLee/addAndRemoveShop
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/applelg/article/details/47381613