iOS开发UI之自定义View

1. 通过代码自定义View,创建一个View类(继承UIView),一个View中包含一个UIImageView和一个UILabel

  • 外界用alloc] init]方法创建对象时,系统默认会自动调用initWithFrame:(CGRect)frame方法,所以要创建对象View中的子控件需要重写initWithFrame:(CGRect)frame方法,在这个方法中来创建子控件,但不能对其根据创建这个类创建出来的对象尺寸来设置,需要调用

    - (void)layoutSubviews 这个方法(当控件尺寸发生改变时就会调用),当在UIControlView.m中创建这个对象,并给它设置尺寸时就会调用这个方法,这时就可以在这个方法中来设置,这个类中的子控件就可以根据对象尺寸来设置自己的尺寸

  • 所以一般这这个类中对外提供一个类工厂方法并将

  1. #import "LDPackageView.h"
  2. #import "LDPackage.h"
  3. @interface LDPackageView ()
  4. @property (nonatomic, weak) UIImageView *iconImage;
  5. @property (nonatomic, weak) UILabel *nameLabel;
  6. @property (nonatomic, strong) LDPackage *package;
  7. @end
  8. @implementation LDPackageView
  9. - (instancetype)initWithPackage:(LDPackage *)package
  10. {
  11.    if (self = [super init]) {
  12.        _package = package;
  13.        // 1.创建UIImageView
  14.        UIImageView *iconImage = [[UIImageView alloc] init];
  15.        self.iconImage = iconImage;
  16.        self.iconImage.image = [UIImage imageNamed:package.icon];
  17.        [self addSubview:iconImage];
  18.        
  19.        // 2.创建UILabel
  20.        UILabel *nameLabel = [[UILabel alloc] init];
  21.        self.nameLabel = nameLabel;
  22.        self.nameLabel.text = package.name;
  23.        [self addSubview:nameLabel];
  24.        
  25.    }
  26.    return self;
  27. }
  28. + (instancetype)packageViewWithPackage:(LDPackage *)package
  29. {
  30.    return [[self alloc] initWithPackage:package];
  31. }
  32. /**
  33. *  当控件尺寸发生改变时就会调用这个方法
  34. */
  35. - (void)layoutSubviews
  36. {

        [super layouSubviews];

  37.    // 1.设置iconImage的尺寸和位置
  38.    CGFloat iconImageW = self.bounds.size.width;
  39.    CGFloat iconImageH = iconImageW;
  40.    CGFloat iconImageX = 0;
  41.    CGFloat iconImageY = 0;
  42.    self.iconImage.frame = CGRectMake(iconImageX, iconImageY, iconImageW, iconImageH);
  43.    
  44.    // 2.设置nameLabel的尺寸和位置
  45.    CGFloat nameLabelW = iconImageW ;
  46.    CGFloat nameLabelH = self.bounds.size.height - iconImageH;
  47.    CGFloat nameLabelX = 0;
  48.    CGFloat nameLabelY = iconImageH;
  49.    self.nameLabel.frame = CGRectMake(nameLabelX, nameLabelY, nameLabelW, nameLabelH);
  50.    self.nameLabel.textAlignment = NSTextAlignmentCenter;
  51.    self.nameLabel.font = [UIFont systemFontOfSize:13];
  52. }
  53. @end

2. 通过xib定义View,创建View来管理xib

    1> 创建一个xib文件用来描述View中子View布局

    2> 创建一个继承与UIView的类,把xib文件和这个类关联

    3> 将xib中的子控件托线到关联的类(属性)

    4> 外界用这个类创建对象时不会调用- (void)init;- (instancetype)initWithFrame:(NSRect)rect; 这两个初始化方法,即不能通过alloc] init]方法来创建,当加载xib时就会调用- (id)initWithCoder: 方法 ,xib已经加载好后再执行- (void)awakerFromNib 方法

    5> 在创建View对象和View中的子控件时都会调用initWithCoder:

如果xib或者storyboard选中autolayout

如果控件从xib或者storyboard中加载出来,如果该控件还没有显示,是不能通过设置frame来改变控件的尺寸


 setFrame : xib众加载出来对象就会调用该方法

 setImageNames : 主动调用

 layoutSubviews : xib或者storyboard中加载出来的控件,在控件显示出来之后,才会调用(如果该控件已经显示了,只要改变尺寸就会调用该方法)


使用autolayout和不使用autolayout的却别

 使用autolayout : 在调用layoutSubViews方法的时候,会将子控件frame设置成xib中加载出来的frame

 不使用autolayout : 在调用layoutSubViews方法的时候,不会将子控件frame设置会xib加载出来的frame


对外提供创建对象的接口如下:

  1. - (instancetype)initWithProduct:(LDProduct *)product
  2. {
  3.    LDProductView *productView = nil;
  4.    if (self = [super init]) {
  5.        productView = [[[NSBundle mainBundle] loadNibNamed:@"LDProductView" owner:nil options:nil] firstObject];
  6.        productView.product = product;
  7.        
  8.        productView.imageView.image = [UIImage imageNamed:product.icon];
  9.        productView.nameLabel.text = product.name;
  10.    }
  11.    return productView;
  12. }
  13. + (instancetype)productViewWithProduct:(LDProduct *)product
  14. {
  15.    return [[self alloc] initWithProduct:product];
  16. }
  • 当加载xib的过程中就会执行改方法

  1. - (id)initWithCoder:(NSCoder *)aDecoder
  2. {
  3.    if (self = [super initWithCoder:aDecoder]) {
  4.        // NSLog(@"initWithCoder");
  5.        // self.backgroundColor = [UIColor purpleColor];
  6.    }
  7.    return self;
  8. }
  • 当xib已经加载好的时候就会执行该方法

  1. - (void)awakeFromNib
  2. {
  3.    [super awakeFromNib];
  4.    
  5.    self.backgroundColor = [UIColor purpleColor];
  6. }

3.自定义UIButton类继承UIButton(UIButton内部已经有了UIImageView和UILabel这2个控件)

1> 修改UIButton内部的子控件的frame需要重写父类中两个方法

  • 修改子控件UIImageView的frame

  1. - (CGRect)imageRectForContentRect:(CGRect)contentRect
  2. {
  3.    CGFloat width = self.bounds.size.width;
  4.    CGFloat height = width;
  5.    return CGRectMake(0, 0, width, height);
  6. }
  • 修改子控件UILabel的frame

  1. - (CGRect)titleRectForContentRect:(CGRect)contentRect
  2. {
  3.    CGFloat width = self.bounds.size.width;
  4.    CGFloat height = self.bounds.size.height - width;
  5.    return CGRectMake(0, width, width, height);
  6. }

2> 对外提供一个方法来创建UIButton按钮

  1. // 外界提供一个数据模型,传入后将模型中对象的属性赋值给UIImageView和UILabel
  2. - (instancetype)initWithProduct:(LDProduct *)product
  3. {
  4.    if (self = [super init]) {
  5.        _product = product;
  6.        [self setImage:[UIImage imageNamed:product.icon] forState:UIControlStateDisabled];
  7.        [self setTitle:product.name forState:UIControlStateNormal];
  8.        [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  9.        self.titleLabel.textAlignment = NSTextAlignmentCenter;
  10.        self.enabled = NO;
  11.    }
  12.    return self;
  13. }
  14. + (instancetype)buttonWithProduct:(LDProduct *)product
  15. {
  16.    return [[self alloc] initWithProduct:product];
  17. }
posted @ 2015-09-27 17:01  文刂Rn  阅读(391)  评论(0编辑  收藏  举报