UIView自定义注意点

界面:代码 vs Xib

  • 代码:提供xxxView.h 和 xxxView.m两个文件
    PAChartView-code

  • xib:提供xxxView.h 和 xxxView.m和xxxView.xib三个文件
    PAChartView-xib

  • xib:需要拖动IBOutlet引用界面元素

  • xib:要用加载函数将界面资源加载进来,然后使用

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
UIView *view = nib[0];
[self addSubview:view];
  • 一般自定义UIView都是公共控件,并且还会用到CALayer,所以还是用纯代码写界面比较好。

初始化函数

  • 只需要重写initWithFrame:就可以了。因为当外部调用init的方法的时候,其内部也会默默地调用initWithFrame:方法

  • 一般的格式:

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.imageView = [[UIImageView alloc]init];
        [self addSubview:self.imageView];

        self.label = [[UILabel alloc]init];
        [self addSubview:self.label];
    }
    return self;
}
  • 初始化函数,主要是子视图的生成函数,这里不需要有布局信息。

  • 可以根据情况,提供便利的初始化函数,这种函数需要写到h文件中,比如:

- (instancetype)initWithTitle:(NSString *)title andImage:(UIImage *)image {
    self = [self init];
    if (self) {
        self.label.text = title;
        self.imageView.image = image;
    }
    return self;
}

布局

  • 在layoutSubViews方法里面布局

  • 要先调用父类的layoutSubviews方法,不然在iOS7中可能会崩溃

  • 如果要更新布局,调用函数[self setNeedsLayout];

- (void)layoutSubviews {
    // 确定子控件的frame(这里得到的self的frame/bounds才是准确的)
    CGFloat width = self.bounds.size.width;
    CGFloat height = self.bounds.size.height;
    self.imageView.frame = CGRectMake(0, 0, width, width);
    self.label.frame = CGRectMake(0, width, width, height - width);

    // 一定要调用super的方法,并且放在后面比较好,不然iOS7可能会崩溃
    [super layoutSubviews];
}
  • layoutSubViews中可以直接使用frame,需要用到的时候可以用。

  • 如果是AutoLayout,建议使用第三方库Masonry,布局内容写在专门的布局函数中

// tell UIKit that you are using AutoLayout
+ (BOOL)requiresConstraintBasedLayout {
    return YES;
}

// this is Apple's recommended place for adding/updating constraints
- (void)updateConstraints {

    // --- remake/update constraints here
    [self.button remakeConstraints:^(MASConstraintMaker *make) {
        make.width.equalTo(@(self.buttonSize.width));
        make.height.equalTo(@(self.buttonSize.height));
    }];

    //according to apple super should be called at end of method
    [super updateConstraints];
}

对外接口:属性 vs 方法

  • 使用默认的getter和setter方法,不要自定义

  • 如果只是普通的设置和读取,不会做额外的事情,那么用属性方便一点

  • 如果要做额外的事情,用方法,不要重写setter方法

  • 如果会引起布局调整,用方法,不要重写setter方法,在方法内部调用[self setNeedsLayout];

参考文章

使用代码自定义UIView注意一二三

你可能感兴趣的:(UIView自定义注意点)