源码-03-封装
封装
1 #import "ViewController.h" 2 #import "XMGShop.h" 3 4 @interface ViewController () 5 /** 存放所有商品的整体 */ 6 @property (weak, nonatomic) IBOutlet UIView *shopsView; 7 8 /** HUD */ 9 @property (weak, nonatomic) IBOutlet UILabel *hud; 10 11 // 文档注释 12 /** 添加按钮 */ 13 @property (weak, nonatomic) UIButton *addBtn; 14 /** 删除按钮 */ 15 @property (weak, nonatomic) UIButton *removeBtn; 16 17 /** 全部商品数据 */ 18 @property (strong, nonatomic) NSArray *shops; 19 @end 20 21 @implementation ViewController 22 23 // 加载plist数据(比较大) 24 // 懒加载:用到时再去加载,而且也只加载一次 25 - (NSArray *)shops 26 { 27 if (_shops == nil) { 28 // 加载一个字典数组 29 NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"shops" ofType:@"plist"]]; 30 31 NSMutableArray *shopArray = [NSMutableArray array]; 32 for (NSDictionary *dict in dictArray) { 33 XMGShop *shop = [XMGShop shopWithDict:dict]; 34 [shopArray addObject:shop]; 35 } 36 _shops = shopArray; 37 } 38 return _shops; 39 } 40 41 - (void)viewDidLoad 42 { 43 [super viewDidLoad]; 44 45 // 添加“添加按钮” 46 self.addBtn = 。。。 47 48 // 添加“删除按钮” 49 self.removeBtn = 。。。 50 self.removeBtn.enabled = NO; 51 } 52 53 #pragma mark 添加按钮 54 - (UIButton *)addButtonWithImage:(NSString *)image highImage:(NSString *)highImage disableImage:(NSString *)disableImage
frame:(CGRect)frame action:(SEL)action 55 { 56 // 创建按钮 57 UIButton *btn = [[UIButton alloc] init]; 58 // 设置背景图片 59 [btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal]; 60 [btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted]; 61 [btn setBackgroundImage:[UIImage imageNamed:disableImage] forState:UIControlStateDisabled]; 62 // 设置位置和尺寸 63 btn.frame = frame; 64 // 监听按钮点击 65 [btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; 66 // 添加按钮 67 [self.view addSubview:btn]; 68 return btn; 69 } 70 71 #pragma mark 添加 72 - (void)add 73 { 74 75 CGFloat shopW = 80; // 每一个商品的尺寸 76 CGFloat shopH = 90; 77 78 int cols = 3; // 一行的列数 79 80 CGFloat colMargin = (self.shopsView.frame.size.width - cols * shopW) / (cols - 1); // 每一列之间的间距 81 CGFloat rowMargin = 10; // 每一行之间的间距 82 83 UIView *shopView = [[UIView alloc] init]; // 创建一个父控件(整体:存放图片和文字) 84 shopView.backgroundColor = [UIColor redColor]; 85 86 NSUInteger index = self.shopsView.subviews.count; // 商品的索引 87 88 NSUInteger col = index % cols; // 商品的x值 89 CGFloat shopX = col * (shopW + colMargin); 90 91 NSUInteger row = index / cols; // 商品的y值 92 CGFloat shopY = row * (shopH + rowMargin); 93 94 shopView.frame = CGRectMake(shopX, shopY, shopW, shopH); 95 [self.shopsView addSubview:shopView]; 96 97 // 获得index位置对应的商品数据 98 // NSDictionary *dict = self.shops[index]; 99 // Shop *shop = [Shop shopWithDict:dict]; 100 101 XMGShop *shop = self.shops[index]; 102 103 // 添加图片 104 UIImageView *iconView = [[UIImageView alloc] init]; 105 iconView.image = [UIImage imageNamed:shop.icon]; 106 iconView.frame = CGRectMake(0, 0, shopW, shopW); 107 iconView.backgroundColor = [UIColor blueColor]; 108 [shopView addSubview:iconView]; 109 110 // 添加文字 111 UILabel *label = [[UILabel alloc] init]; 112 label.text = shop.name; 113 label.frame = CGRectMake(0, shopW, shopW, shopH - shopW); 114 label.font = [UIFont systemFontOfSize:11]; 115 label.textAlignment = NSTextAlignmentCenter; 116 [shopView addSubview:label]; 117 118 // 控制按钮的可用性 119 [self checkState]; 120 } 121 122 #pragma mark 删除 123 - (void)remove 124 { 125 [[self.shopsView.subviews lastObject] removeFromSuperview]; 126 127 // 控制按钮的可用性 128 [self checkState]; 129 } 130 131 #pragma mark 检查状态:按钮状态 132 - (void)checkState 133 { 134 // 删除按钮什么时候可以点击:商品个数 > 0 135 self.removeBtn.enabled = (self.shopsView.subviews.count > 0); 136 // 添加按钮什么时候可以点击:商品个数 < 总数 137 self.addBtn.enabled = (self.shopsView.subviews.count < self.shops.count); 138 139 // 显示HUD 140 NSString *text = nil; 141 if (self.removeBtn.enabled == NO) { // 删光了 142 text = @"已经全部删除"; 143 } else if (self.addBtn.enabled == NO) { // 加满了 144 text = @"已经添加满了"; 145 } 146 if (text == nil) return; 147 148 self.hud.text = text; 149 self.hud.alpha = 1.0; 150 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 151 self.hud.alpha = 0.0; 152 }); 153 } 154 155 @end
shops.h
1 #import <Foundation/Foundation.h> 2 3 @interface XMGShop : NSObject 4 /** 商品名称 */ 5 @property (nonatomic, strong) NSString *name; 6 /** 图标 */ 7 @property (nonatomic, strong) NSString *icon; 8 9 - (instancetype)initWithDict:(NSDictionary *)dict; 10 + (instancetype)shopWithDict:(NSDictionary *)dict; 11 @end
shops.m
1 #import "XMGShop.h" 2 3 @implementation XMGShop 4 - (instancetype)initWithDict:(NSDictionary *)dict 5 { 6 if (self = [super init]) { 7 self.name = dict[@"name"]; 8 self.icon = dict[@"icon"]; 9 } 10 return self; 11 } 12 13 + (instancetype)shopWithDict:(NSDictionary *)dict 14 { 15 return [[self alloc] initWithDict:dict]; 16 } 17 @end
控制器知道的太多,自定义封装控件

三大步骤:1.初始化的时候添加控件。2.layoutSubviews中布局子控件。3.重写模型的setter方法,拿到模型数据赋值给子控件。
(尺寸、位置、数据)
ViewController.m
9 #import "ViewController.h" 10 #import "XMGShop.h" 11 #import "XMGShopView.h" 12 13 @interface ViewController () 14 /** 存放所有商品的整体 */ 15 @property (weak, nonatomic) IBOutlet UIView *shopsView; 16 17 /** HUD */ 18 @property (weak, nonatomic) IBOutlet UILabel *hud; 19 20 // 文档注释 21 /** 添加按钮 */ 22 @property (weak, nonatomic) UIButton *addBtn; 23 /** 删除按钮 */ 24 @property (weak, nonatomic) UIButton *removeBtn; 25 26 /** 全部商品数据 */ 27 @property (strong, nonatomic) NSArray *shops; 28 @end 29 30 @implementation ViewController 31 32 // 加载plist数据(比较大) 33 // 懒加载:用到时再去加载,而且也只加载一次 34 - (NSArray *)shops 35 { 36 if (_shops == nil) { 37 // 1、加载一个字典数组 38 NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"shops" ofType:@"plist"]]; 39 //2、字典数组转模型数组 40 NSMutableArray *shopArray = [NSMutableArray array]; 41 for (NSDictionary *dict in dictArray) { 42 XMGShop *shop = [XMGShop shopWithDict:dict]; 43 [shopArray addObject:shop]; 44 } 45 //3.赋值 46 _shops = shopArray; 47 } 48 return _shops; 49 } 50 51 - (void)viewDidLoad 52 { 53 [super viewDidLoad]; 54 55 // 添加“添加按钮” 56 self.addBtn = [self addButtonWithImage:@"add" highImage:@"add_highlighted" disableImage:@"add_disabled"
frame:CGRectMake(30, 30, 50, 50) action:@selector(add)]; 57 58 // 添加“删除按钮” 59 self.removeBtn = [self addButtonWithImage:@"remove" highImage:@"remove_highlighted" disableImage:@"remove_disabled"
frame:CGRectMake(270, 30, 50, 50) action:@selector(remove)]; 60 self.removeBtn.enabled = NO; 61 } 62 63 #pragma mark 添加按钮 64 - (UIButton *)addButtonWithImage:(NSString *)image highImage:(NSString *)highImage disableImage:(NSString *)disableImage
frame:(CGRect)frame action:(SEL)action 65 { 66 // 创建按钮 67 UIButton *btn = [[UIButton alloc] init]; 68 // 设置背景图片 69 [btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal]; 70 [btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted]; 71 [btn setBackgroundImage:[UIImage imageNamed:disableImage] forState:UIControlStateDisabled]; 72 // 设置位置和尺寸 73 btn.frame = frame; 74 // 监听按钮点击 75 [btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; 76 // 添加按钮 77 [self.view addSubview:btn]; 78 return btn; 79 } 80 81 #pragma mark 添加 82 - (void)add 83 { 84 // 每一个商品的尺寸 85 CGFloat shopW = 80; 86 CGFloat shopH = 90; 87 88 // 一行的列数 89 int cols = 3; 90 91 // 每一列之间的间距 92 CGFloat colMargin = (self.shopsView.frame.size.width - cols * shopW) / (cols - 1); 93 // 每一行之间的间距 94 CGFloat rowMargin = 10; 95 96 // 创建一个父控件(整体:存放图片和文字) 97 XMGShopView *shopView = [XMGShopView shopView]; 98 99 // 商品的索引 100 NSUInteger index = self.shopsView.subviews.count; 101 // 给商品控件传递商品模型 102 shopView.shop = self.shops[index]; 103 104 // 商品的x值 105 NSUInteger col = index % cols; 106 CGFloat shopX = col * (shopW + colMargin); 107 108 // 商品的y值 109 NSUInteger row = index / cols; 110 CGFloat shopY = row * (shopH + rowMargin); 111 112 shopView.frame = CGRectMake(shopX, shopY, shopW, shopH); 113 114 // 添加控件 115 [self.shopsView addSubview:shopView]; 116 117 // 控制按钮的可用性 118 [self checkState]; 119 } 120 121 #pragma mark 删除 122 - (void)remove 123 { 124 [[self.shopsView.subviews lastObject] removeFromSuperview]; 125 126 // 控制按钮的可用性 127 [self checkState]; 128 } 129 130 #pragma mark 检查状态:按钮状态 131 - (void)checkState 132 { 133 // 删除按钮什么时候可以点击:商品个数 > 0 134 self.removeBtn.enabled = (self.shopsView.subviews.count > 0); 135 // 添加按钮什么时候可以点击:商品个数 < 总数 136 self.addBtn.enabled = (self.shopsView.subviews.count < self.shops.count); 137 138 // 显示HUD 139 NSString *text = nil; 140 if (self.removeBtn.enabled == NO) { // 删光了 141 text = @"已经全部删除"; 142 } else if (self.addBtn.enabled == NO) { // 加满了 143 text = @"已经添加满了"; 144 } 145 if (text == nil) return; 146 147 self.hud.text = text; 148 self.hud.alpha = 1.0; 149 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 150 self.hud.alpha = 0.0; 151 }); 152 } 153 154 @end
// XMGShop.h// 存放商品数据的模型 #import <Foundation/Foundation.h> @interface XMGShop : NSObject /** 商品名称 */ @property (nonatomic, strong) NSString *name; /** 图标 */ @property (nonatomic, strong) NSString *icon; - (instancetype)initWithDict:(NSDictionary *)dict; + (instancetype)shopWithDict:(NSDictionary *)dict; @end
// XMGShop.m
@implementation XMGShop - (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
自定义的View(封装插件)
XMGShopView.h
XMGShopView.m
// XMGShopView.h #import <UIKit/UIKit.h> @class XMGShop; @interface XMGShopView : UIView /** 商品模型 */ @property (nonatomic, strong) XMGShop *shop; + (instancetype)shopView; @end
// XMGShopView.m // 03-综合使用 #import "XMGShopView.h" #import "XMGShop.h" @interface XMGShopView() /** 图片控件 */ @property (nonatomic, strong) UIImageView *iconView; /** 名字控件 */ @property (nonatomic, strong) UILabel *nameLabel; @end @implementation XMGShopView + (instancetype)shopView { return [[self alloc] init]; } - (UIImageView *)iconView { if (_iconView == nil) { UIImageView *iconView = [[UIImageView alloc] init]; iconView.backgroundColor = [UIColor blueColor]; [self addSubview:iconView]; _iconView = iconView; } return _iconView; } - (UILabel *)nameLabel { if (_nameLabel == nil) { UILabel *nameLabel = [[UILabel alloc] init]; nameLabel.font = [UIFont systemFontOfSize:11]; nameLabel.textAlignment = NSTextAlignmentCenter; nameLabel.backgroundColor = [UIColor redColor]; [self addSubview:nameLabel]; _nameLabel = nameLabel; } return _nameLabel; } /** init方法内部会自动调用initWithFrame:方法 // */ //- (instancetype)initWithFrame:(CGRect)frame //{ // if (self = [super initWithFrame:frame]) { // self.backgroundColor = [UIColor orangeColor]; // // // 添加图片 // UIImageView *iconView = [[UIImageView alloc] init]; // iconView.backgroundColor = [UIColor blueColor]; // [self addSubview:iconView]; // self.iconView = iconView; // // // 添加文字 // UILabel *nameLabel = [[UILabel alloc] init]; // nameLabel.font = [UIFont systemFontOfSize:11]; // nameLabel.textAlignment = NSTextAlignmentCenter; // nameLabel.backgroundColor = [UIColor redColor]; // [self addSubview:nameLabel]; // self.nameLabel = nameLabel; // } // return self; //} /** * 这个方法专门用来布局子控件,一般在这里设置子控件的frame * 当控件本身的尺寸发生改变的时候,系统会自动调用这个方法layoutSubviews * */ - (void)layoutSubviews{ // 一定要调用super的layoutSubviews [super layoutSubviews]; CGFloat shopW = self.frame.size.width; CGFloat shopH = self.frame.size.height; self.iconView.frame = CGRectMake(0, 0, shopW, shopW); self.nameLabel.frame = CGRectMake(0, shopW, shopW, shopH - shopW); } - (void)setShop:(XMGShop *)shop { _shop = shop; self.nameLabel.text = shop.name; self.iconView.image = [UIImage imageNamed:shop.icon]; } @end
自定义控件使用
导入头文件
1.创建对象,2.传模型,3.设置尺寸;
本人无商业用途,仅仅是学习做个笔记,特别鸣谢小马哥,学习了IOS,另日语学习内容有需要文本和音频请关注公众号:riyuxuexishuji

浙公网安备 33010602011771号