步骤:
1.继承UIView 创建一个myView
#import <UIKit/UIKit.h>
@interface myView : UIView
@property(nonatomic,strong)UIButton *btn;
@property(nonatomic,strong)UILabel *label;
2.重写initWithFrame 方法。
问题:为什么不重写init 方法呢?
因为有可能别人会用你的myView,他可能创建对象的方式是
myView *v = [[UIView alloc] initWithFrame:CGRectMake(100, 0, 100, 100)]; 这样的话 你写在init方法中的子控件就不会被创建,运行后就不会显示子控件了。而重写initWithFrame的话,不管别人是init 还是initWithFrame 都会调用到initWithFrame, 因为init方法内部是会调用initWithFrame方法的。
3.重新initWithFrame 方法时。
如果子控件imageView的宽和高直接用self.frame.size.width,这种形式的话(如下面代码1),这个时候self.frame 可能没值,因为如果外部调用了MyView的init方法,也会执行到这里,这个时候frame还没有赋值,会导致无法显示子控件。
如果你是写死的frame,比如self.imageView.frame = CGRectMake(0, 0, 100, 100); 这样的就不会有问题。(如下面代码2)
总结:我们最好不要将子控件的frame设置写在initWithFrame中。我们要做的仅仅是把子控件放进去就行了
代码1:
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.imageView = [[UIImageView alloc]init];
self.imageView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.width);
[self addSubview:self.imageView];
}
return self;
}
代码2:仅仅将子控件放进去。
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.imageView = [[UIImageView alloc]init];
[self addSubview:self.imageView];
}
return self;
}
3.在layoutSubViews方法里面布局子控件
- (void)layoutSubviews {
// 一定要调用super的方法
[super layoutSubviews];
// 确定子控件的frame(这里得到的self的frame/bounds才是准确的)
CGFloat width = self.bounds.size.width;
self.imageView.frame = CGRectMake(0, 0, width/2, width);
}