自定义View控件(2—手写实例代码)
1、 步骤:
+ 1.自定义一个类继承于UIView
+ 2.在initWithFrame方法中添加子控件
+ 3.在layoutSubviews中设置子控件的位置
+ 4.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据
- 类工厂方法(便利构造器)
+ 按照苹果的风格和规范, 一般情况一个用于创建对象的对象方法会对应一个类方法
+ 可以通过类工厂方法, 快速的根据数据创建一个对象
- 注意点:
+ 返回值一定要使用instancetype, 不要使用id
+ 在类工厂方法中创建对象, 使用self, 不要使用类名
// **************************************************************************************************
2. 实现自定义View:
/* 1. 定义字典模型 */
// 1> 对应plist文件中的模型数据如:Shop
// 2> 在Shop.h中设置属性,然后声明写字典转模型方法如:
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *icon;- (Shop *)initWithDict:(NSDictionary *)dict;
+ (Shop *)shopWithDict:(NSDictionary *)dict;
// 3> 然后Shop.m中实现Shop.h中的方法:
- (Shop *)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (Shop *)shopWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
//**************************************************************************************************
/* 2. 定义自定义View,继承UIView,例如:ShopView */
// 1> ShopView.h中设置自定义控件拥有那些类型的子控件,
1. 以及拥有一个模型数据(即将展示到自定义控件上的模型),
2. 以及声明工厂方法,达到快速创建自定义控件及其上的数据模型
// 在ShopView.h中
@class Shop;@interface ShopView : UIView@property (nonatomic, weak)UIImageView *iconView;
@property (nonatomic, weak)UILabel *nameView;@property (nonatomic, strong) Shop *shop;- (instancetype)initWithShop:(Shop *)shop;
+ (instancetype)shopViewWithShop:(Shop *)shop;@end
// 2> ShopView.m中:实现.m 中的
1. 实现.h文件中声明的工厂等快速创建自定义控件的方法,
2. 然后因为要设置模型数据和自定义控件上的子控件的数据,所以要重写模型数据的setter方法进行其操作。
3. 因为要实现添加子控件到自定义控件上所以要重写 initWithFrame方法。(因为自定义控件在调用init方法初始化的时候,init方法会调用initWithFrame方法,从而即可将子控件加入到自定义控件上的目的),你也可以选用其他方法来实现增加子控件,而不是必须用initWithFrame才行,只要能达到添加子控件的效果即可。
注意:(不在initWithFrame方法中不要设置其子控件的frame,因为此时自定义控件可能只是做了初始化,而并未设置其frame,所以子控件就无法根据其frame来设置子控件的frame了),
4. 因为要设置自定义控件上子控件的frame,所以要实现其layoutSubViews方法。(layoutSubViews:专门用于设置子控件的frame)
#import "ShopView.h"
#import "Shop.h"@implementation ShopView- (instancetype)initWithShop:(Shop *)shop{if (self = [super init]) {
self.shop = shop;
}
return self;
}+ (instancetype)shopViewWithShop:(Shop *)shop{return [[self alloc] initWithShop:shop];
}- (nonnull instancetype)initWithFrame:(CGRect)frame{if (self = [super initWithFrame:frame]) {
// 1. 子控件imageView创建
UIImageView *subImageView = [[UIImageView alloc] init];
[self addSubview:subImageView];
self.iconView = subImageView;// 2. 子控件lable创建
UILabel *subLable = [[UILabel alloc] init];
subLable.text = self.shop.name;
subLable.textAlignment = UITextAlignmentCenter;[self addSubview:subLable];
self.nameView = subLable;
}
return self;
}- (void)layoutSubviews{
[super layoutSubviews];self.iconView.frame = CGRectMake(0, 0, 70, 70);
self.nameView.frame = CGRectMake(0, 70, 70 , 30);
}- (void)setShop:(Shop *)shop{_shop = shop;
self.iconView.image = [UIImage imageNamed:self.shop.icon];
self.nameView.text = self.shop.name;
}
@end
// **************************************************************************************************
// 3. 在控制器文件中,要做的就是获取模型数据,然后依次将模型数据展示到自定义控件上显示即可。
1. 拥有模型数据:
1> 在控制器中设置一个保存模型plist文件中模型数组的属性。
@property (nonatomic, strong) NSArray *shops;
2> 重写shops属性模型的getter方法,从而得到我们想要的模型数组集合,我们可以解析plist文件获取到模型数组。设置模型数组,通过懒加载解析plist文件中数据进行初始化操作即可。
// 懒加载
- (NSArray *)shops{NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"shops.plist" ofType:nil]];
NSMutableArray *shopsArray = [NSMutableArray array];for (NSDictionary *dict in dictArray) {Shop *shop = [Shop shopWithDict:dict];
[shopsArray addObject:shop];
}_shops = shopsArray;return _shops;
}
2. 现在我们即可初始化一个自定义控件出来,然后设置其模型数据,最后将其添加到控制器的view中即可显示
ShopView *shopView = [ShopView shopViewWithShop:self.shops[index]]; // 声明并初始化指定模型的数据到自定义的控件上。
//(你要明白:这句代码将要干什么事情:
// @1:它会调用在shopViewWithShop:从而间接调用init方法,然而在init方法中系统会自动调用initWithFrame方法,所有这时它又会调用initWithFrame方法从而实现了添加子控件到自定义控件上。
// @2:ShopView类的shopViewWithShop:方法 -》对象方法initWithShop:来初始化一个自定义的控件,从而间接调用init方法,然而在init方法中系统会自动调用initWithFrame方法,所有这时它又会调用initWithFrame方法从而实现了添加子控件到自定义控件上。并且将传入的模型将其设置到自定义控件的模型数据属性,这样就会调用其set方法setShop:,在set方法中就会完成,将模型数据展示到控件上展示数据了。
)
// 4. 计算自定义控件添加到的frame
shopView.frame = CGRectMake(subViewX, subViewY, subViewWidth, 70);
// 5. 将搭建好的自定义控件添加到控制器的view上
[self.view addSubview:shopView];
转载于:https://www.cnblogs.com/cjpBlog/p/4644319.html
自定义View控件(2—手写实例代码)相关推荐
- Android中通过自定义签名控件实现手写签名
场景 实现手写签名并获取签名照片 注: 博客: BADAO_LIUMANG_QIZHI的博客_霸道流氓气质_CSDN博客-C#,SpringBoot,架构之路领域博主 关注公众号 霸道的程序猿 获取编 ...
- iOS自定义View 控件自动计算size能力
iOS自定义View 控件自动计算size能力 背景 在使用 UILabel 和 UIImage 的时候,不用指定宽高约束,控件也不会报约束缺失,还可以根据内容自己确定适合的宽高,特别适合 Xib 和 ...
- 安卓中自定义view控件代替radiogroup实现颜色渐变效果的写法
利用自定义控件代替radiogroup,同时实现在使用viewpager进行翻页的时候,实现颜色渐变的效果. 一: 首先创建一个自定义view类继承自View类,所有的控件均用canvas绘制出来(包 ...
- android 自定义view控件,Android 自定义View——自定义View控件
Android给我们提供了大量的View控件,但这还是远远满足不了我们的要求,有时候开发所需要的控件形式是在Android提供的控件中是不存在,这就需要我们自己去定义一个.那么如何自定义控件? 学习自 ...
- Android自定义View控件
转自:http://blog.csdn.net/lvwenbo0107/article/details/50542597 写的够详细了 为什么要自定义控件 1.特定的显示风格. 2.处理特有的用户交互 ...
- ios swift 纯代码自定义view(控件) XYswitchView
文章目录 1.截图 2.代码 2.1 XYswitchView.swift 2.2 LoginVC.swift 3.参考博客 1.截图 2.代码 2.1 XYswitchView.swift impo ...
- android简单的自定义涂鸦控件
简单的自定义涂鸦控件,没有写自定义属性 java代码中找到view后直接setBitmap(Bitmap bitmap)后就可以使用了 提供清除方法clear() 保存可以参考另一篇view转bitm ...
- 创建自定义验证控件(1)
写一个创建自定义的控件的文章.帮大家了解如何写自定义验证控件. 首先写个简单的,长度验证控件,大家在写用户注册的时候,很多时候需要验证用户密码长度在多少到多少之间. 我们通过从BaseValidato ...
- Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,相似图片浏览器
MAC : XCode -> Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,类似图片浏览器 STEP1:将两个目录复制到project里面ImageBrowser ...
最新文章
- MySQL删除存储过程(DROP PROCEDURE)
- 涂格子游戏html,网页版方格贪吃蛇游戏html源码分享
- 如何进行良好的程序设计(1)
- 数据分析与挖掘实战-窃电漏电用户的发现
- mini_magick上传图片
- RFID 打印机是什么
- 由递推关系到通项公式
- Sublime Text3 Emmet用法
- 三进制计算机_要做一个编程界优秀的攀登者,首先要认真计算机中的0和1
- 如何验证 nginx.conf 是否配置正确
- 使用opencv-python读取webm格式的视频并转换成图片和avi格式的视频
- android磁盘分区格式,转:磁盘分区表格式之android分区GPT
- excel分离中英文
- Supervisor进程管理详解
- 数学基础(5)凸优化、最优化理论基础
- 大学计算机技术导论,北京邮电大学计算机学院网络技术导论第一章资料.ppt
- 京东Deco 智能代码体验版正式上线啦,快来体验设计稿一键生成代码~
- Java面向对象编程——继承
- vue3.0实现标签云(或词云)
- 使用Spreadsheet Compare工具对比Excel文件差异
热门文章
- 【HDU - 5914 】Triangle (打表 或 set维护)
- 图解算法学习笔记(二): 选择排序
- 遍历这些字符串,如果字符串没有包含数字的, * 就将字符串中的小写字母转成大写字母并打印字符串
- php批量下载网络图片,php批量下载网页图片并替换路径为本地
- leetcode270. 最接近的二叉搜索树值
- leetcode349. 两个数组的交集
- leetcode97 交错字符串
- android定时循环,Android AlarmManager实现定时循环后台任务
- java五子棋源代码_java 五子棋游戏源码
- linux加密框架 crypto 算法管理 - 算法查找接口 crypto_alg_lookup函数