自定义View控件(手写,xib)须知

 1. 目的 :提高代码的复用性,屏蔽内部的实现细节

2. 步骤
    * 1> 自定义一个类继承于UIView
   * 2> 在initWithFrame方法中添加子控件
   * 3> 在layoutSubviews中设置子控件的位置
   * 4> 提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据
3. 类工厂方法(便利构造器):
   * 按照苹果的风格和规范, 一般情况一个用于创建对象的对象方法会对应一个类方法
   * 可以通过类工厂方法, 快速的根据数据创建一个对象
4. 注意点:
   * 返回值一定要使用instancetype, 不要使用id
   * 在类工厂方法中创建对象, 使用self, 不要使用类名

5. 误区:
/* 1. 手动写代码创建自定义控件,不建议在自定义控件init中设置自定义控件的子控件frame,建议使用 layoutSubviews 方法来设置子控件的位置frame*/

// layoutSubviews方法:专门用于设置子控件的frame

// 比如: ShopView *shopView = [[ShopView alloc] init];
// 后设置 frame,然后你在调用自定义控件的init方法时,自定义控件的frame还没有值,所有子控件无法根据自定义控件的frame来,设置其子控件的frame
shopView.frame = CGRectMake(100, 100, 100, 100);

因为你可能调用init方法时,自定义的控件的frame还没有设置,所有在
自定义的控件的init方法,无法根据父控件位置设置其子控件的位置。

// 解决方案:
所有我们一般重写 - (void)layoutSubviews方法中,设置自定义控件的子控件的位置.
注意:别忘了在layoutSubviews方法中调用[super layoutSubviews];然后设置子控件的frame

/* 2. 子控件设置成weak不会释放,*/

是因为它添加到父控件中,父控件会将其添加到subViews数组中,
数组强引用了它,所有就算设置成weak,还有强指针指向就不会释放.

/* 3. 假如自定义了一个自定义控件,建议使用init初始化自定义控件,而在自定义控件中用 initWithFrame添加自定义控件的子控件:*/

initWithFrame初始化自定义控件,而自定义控件中使用的是init方法添加子控件,这样子控件不会显示出来,
因为调用自定义控件中的initWithFrame方法,不会调用自定义控件中的init方法。

然而如果,自定义控件用init初始化,而自定义控件中用initWithFrame方法添加子控件,这样子控件就会在自定义控件中显示,
因为:初始化自定义控件使用init方法是会调用子控件initWithFrame方法。(调用init方法时,而initWithFrame方法是会在init方法中调用)

/* 4. layoutSubviews方法 */

// layoutSubviews方法:专门用于设置子控件的frame
// layoutSubViews什么时候调用
// 注意:别忘了在layoutSubviews方法中调用[super layoutSubviews];然后设置子控件的frame

1. 第一次创建控件的时候调用
2. 修改了控件的frame时调用
3. 修改位置x,y坐标时不会调用(注)
4. 设置时,控件frame一样时不会调用(注)

/* 5. xib - 》xcode -> User Interface -> empty/View */

1. 什么是xib:xib和storyboard一样都是用来描述界面的
2. xib是storyboard的前身
3. xib是用来描述一个简单的界面或者局部界面
4. storyboard是来描述整体,界面间跳转,全局界面
5. 加载xib的两种方式:

// 1>loadNibNamed
NSArray * res = [[NSBundle mainBundle] loadNibNamed: .... ];
UIView *view = views.firstObject;

// 2> [UINib nibWithName:....]
UINib *nib = [UINib nibWithNme:....];
NSArray *views = [nib instantiateWithOwner...... ];
UIView *view = views.firstObject;

6. 规律: 一般情况下苹果的方法中要求传入一个bundle参数, 直接传nil就代表mainBundle

/* 6. xib创建自定义控件注意点 */

注意:如果是通过xib或者storyboard创建一个控件,不会调用initWithFrame方法,
而是在“创建时”会调用initWithCoder方法,调用该方法时,控件不一定被创建好了,如果我们打算给xib的控件设置属性,不一定会起作用
而在“创建后”会调用aweakFromNib方法,所有我们可以在两个方法中都拿到xib控件设置属性即可。

/* 7. 利用xib创建自定义View 步骤 */

* 1.新建一个Xib描述界面
   * 2.新建一个继承于Xib界面中父控件类型的类来管理界面
   * 3.在xib中关联界面和类
   * 4.重写awakeFromNib方法, 进行一些初始化
   * 5.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据

- 注意点:
- 不应该在控制器中加载xib, 应该将加载xib的操作封装到自定义view中

+ (instancetype)shopView
{
return [[[NSBundle mainBundle] loadNibNamed:@"XMGShopView" owner:nil options:nil] firstObject];
}

- 方法的执行顺序
   + 如果是通过xib或者Storyboard创建一个控件, 不会调用initWithFrame方法
   + 在"创建时"会调用initWithCoder方法
         * 控件不一定被创建好了
    + 在"创建后"会调用awakeFromNib
         * 控件一定被创建好了

/* 8. xib启动原理 */

+ 1. 根据custom class创建对象

XMGShopView *shopView = [XMGShopView alloc] init];

+ 2. 根据xib中的设置, 设置控件的相关属性

shopView.backgroundColor = [UIColor redColor];
shopView.frame = CGRectMake(0, 0, 70, 100);

+ 3. 创建所有子控件, 并且设置子控件的属性

UIImageView *iv = [[UIImageView alloc] init];
iv.frame = CGRectMake(0, 0, 70, 70);
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(0, 70, 70, 30);

+ 4. 检查子控件是否有连线, 如果有就进行关联

self.iconView = iv;
self.nameLabel = label;

+ 5.将所有子控件添加到父控件中

[shopView addSubview:iv];
[shopView addSubview:label];
时间: 2024-10-05 23:28:25

自定义View控件(手写,xib)须知的相关文章

自定义View控件(2—手写实例代码)

1. 步骤: + 1.自定义一个类继承于UIView + 2.在initWithFrame方法中添加子控件 + 3.在layoutSubviews中设置子控件的位置 + 4.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据 - 类工厂方法(便利构造器) + 按照苹果的风格和规范, 一般情况一个用于创建对象的对象方法会对应一个类方法 + 可以通过类工厂方法, 快速的根据数据创建一个对象 - 注意点: + 返回值一定要使用instancetype, 不要使用id +

自定义View控件(1—xib实例代码)

/** * 1. 设置显示到控制器上的模型数据(根据plist文件设置其属性,然后定义与实现工厂方法来快速实现字典转模型) */   // 1. 模型Shop.h文件 @interface Shop : NSObject @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *icon; - (Shop *)initWithDict:(NSDictionary *)dict; +

Android 自定义View控件

一.简介 在自定义View时,我们通常会重写onDraw()方法来绘制View的显示内容.如果,该View还需要使用wrap_content属性,那么还必须重写onMeasure()方法.另外,通过自定义attrs属性,还可以设置新的属性配置值. 在View中通常有以下一些比较重要的回调方法: onFinisInflate():从XML加载组件后回调: onSizeChanged():组件大小改变时回调: onMeasure():回调该方法来进行测量: onLayout():回调该方法来确定显示

Android自定义View控件

转自:http://blog.csdn.net/lvwenbo0107/article/details/50542597 写的够详细了 为什么要自定义控件 1.特定的显示风格. 2.处理特有的用户交互.(textView支持一些滑动功能) 3.优化我们的布局.(嵌套布局绘制比较慢) 4.封装.(tab页按钮不好看) 如何自定义控件 1.自定义属性声明与获取. 2.测量onMeasure. 3.布局onLayout(ViewGroup才需要) 4.绘制onDraw 5.onTouchEvent 6

Android学习(十七)自定义View控件 TopBar

一.创建自定义TopBar头部菜单条 实现步骤: 1.在values中添加attrs.xml文件,设置自定义属性. 2.添加Topbar类,继承RelativeLayout,实现具体功能. 3.添加到页面上,并设置添加事件. 参考代码: values\attrs.xml <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Top

iOS 用xib自定义view控件 debug笔记

1.在view不是很复杂的情况下,如果多次检查后依旧出现coding-compliant这种情况,干脆彻底删除这个xib重新新建一个xib来做一遍.(至今未明真相) 2.初始化xib中的view的大致步骤: //在superView中调用此方法以初始化此view + (XTTopFloatingView*)instanceXTTopFloatingView{ NSArray *nibView = [[NSBundle mainBundle]loadNibNamed:@"XTTopFloating

自定义组合控件的方法

自定义组合控件 1)编写一个类继承ViewGroup, 2)重写构造方法 3)在XML中配置一个视图,控件初始化时,填充这个视图,并挂载到控件中 4)添加自定义属性 在value目录中,编写一个xml文件,<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="setting_view_style"> <att

【安卓笔记】带自定义属性的view控件

开发中经常需要自定义view控件或者组合控件,某些控件可能需要一些额外的配置.比如自定义一个标题栏,你可能需要根据不同尺寸的手机定制不同长度的标题栏,或者更常见的你需要配置标题栏的背景,这时候,你就会考虑到你写的view的扩展性问题,通常情况下,我们可以为这个自定义的标题栏加上一些setXXX方法,供外界调用,设置其颜色.长度等属性.但是我们都知道,在使用系统控件时,我们大多数情况下并不需要在代码中配置控件,而仅仅只需在布局文件中对控件宽.高.颜色等进行配置,这样做的好处就将UI与业务逻辑解耦,

Android 自定义View修炼-打造完美的自定义侧滑菜单/侧滑View控件(转)

一.概述 在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上 咱们可以自己也写一个自定义的侧滑View控件,其实不难,主要涉及到以下几个要点: 1.对Android中Window类中的DecorView有所了解 2.对Scroller类实现平滑移动效果 3.自定义ViewGroup的实现 首先来看看效果图吧:    下面现在就来说说这里咱们实现侧滑View的基本思路吧,这里我采用的是自定义一个继承于RelativeLayout的控件叫做XC