1. 經過代碼自定義View,建立一個View類(繼承UIView),一個View中包含一個UIImageView和一個UILabelcss
外界用alloc] init]方法建立對象時,系統默認會自動調用initWithFrame:(CGRect)frame方法,因此要建立對象View中的子控件須要重寫initWithFrame:(CGRect)frame方法,在這個方法中來建立子控件,但不能對其根據建立這個類建立出來的對象尺寸來設置,須要調用佈局
- (void)layoutSubviews 這個方法(當控件尺寸發生改變時就會調用),當在UIControlView.m中建立這個對象,並給它設置尺寸時就會調用這個方法,這時就能夠在這個方法中來設置,這個類中的子控件就能夠根據對象尺寸來設置本身的尺寸atom
因此通常這這個類中對外提供一個類工廠方法並將
url
#import "LDPackageView.h"#import "LDPackage.h"@interface LDPackageView ()@property (nonatomic, weak) UIImageView *iconImage;@property (nonatomic, weak) UILabel *nameLabel;@property (nonatomic, strong) LDPackage *package;@end@implementation LDPackageView- (instancetype)initWithPackage:(LDPackage *)package{ if (self = [super init]) { _package = package; // 1.建立UIImageView UIImageView *iconImage = [[UIImageView alloc] init]; self.iconImage = iconImage; self.iconImage.image = [UIImage imageNamed:package.icon]; [self addSubview:iconImage]; // 2.建立UILabel UILabel *nameLabel = [[UILabel alloc] init]; self.nameLabel = nameLabel; self.nameLabel.text = package.name; [self addSubview:nameLabel]; } return self;}+ (instancetype)packageViewWithPackage:(LDPackage *)package{ return [[self alloc] initWithPackage:package];}/** * 當控件尺寸發生改變時就會調用這個方法 */- (void)layoutSubviews{
spa
code
[super layouSubviews]; // 1.設置iconImage的尺寸和位置 CGFloat iconImageW = self.bounds.size.width; CGFloat iconImageH = iconImageW; CGFloat iconImageX = 0; CGFloat iconImageY = 0; self.iconImage.frame = CGRectMake(iconImageX, iconImageY, iconImageW, iconImageH); // 2.設置nameLabel的尺寸和位置 CGFloat nameLabelW = iconImageW ; CGFloat nameLabelH = self.bounds.size.height - iconImageH; CGFloat nameLabelX = 0; CGFloat nameLabelY = iconImageH; self.nameLabel.frame = CGRectMake(nameLabelX, nameLabelY, nameLabelW, nameLabelH); self.nameLabel.textAlignment = NSTextAlignmentCenter; self.nameLabel.font = [UIFont systemFontOfSize:13];}@end
2. 經過xib定義View,建立View來管理xiborm
1> 建立一個xib文件用來描述View中子View佈局對象
2> 建立一個繼承與UIView的類,把xib文件和這個類關聯blog
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
對外提供建立對象的接口以下:
- (instancetype)initWithProduct:(LDProduct *)product{ LDProductView *productView = nil; if (self = [super init]) { productView = [[[NSBundle mainBundle] loadNibNamed:@"LDProductView" owner:nil options:nil] firstObject]; productView.product = product; productView.imageView.image = [UIImage imageNamed:product.icon]; productView.nameLabel.text = product.name; } return productView;}+ (instancetype)productViewWithProduct:(LDProduct *)product{ return [[self alloc] initWithProduct:product];}
當加載xib的過程當中就會執行改方法
- (id)initWithCoder:(NSCoder *)aDecoder{ if (self = [super initWithCoder:aDecoder]) { // NSLog(@"initWithCoder"); // self.backgroundColor = [UIColor purpleColor]; } return self;}
當xib已經加載好的時候就會執行該方法
- (void)awakeFromNib{ [super awakeFromNib]; self.backgroundColor = [UIColor purpleColor];}
3.自定義UIButton類繼承UIButton(UIButton內部已經有了UIImageView和UILabel這2個控件)
1> 修改UIButton內部的子控件的frame須要重寫父類中兩個方法
修改子控件UIImageView的frame
- (CGRect)imageRectForContentRect:(CGRect)contentRect{ CGFloat width = self.bounds.size.width; CGFloat height = width; return CGRectMake(0, 0, width, height);}
修改子控件UILabel的frame
- (CGRect)titleRectForContentRect:(CGRect)contentRect{ CGFloat width = self.bounds.size.width; CGFloat height = self.bounds.size.height - width; return CGRectMake(0, width, width, height);}
2> 對外提供一個方法來建立UIButton按鈕
// 外界提供一個數據模型,傳入後將模型中對象的屬性賦值給UIImageView和UILabel- (instancetype)initWithProduct:(LDProduct *)product{ if (self = [super init]) { _product = product; [self setImage:[UIImage imageNamed:product.icon] forState:UIControlStateDisabled]; [self setTitle:product.name forState:UIControlStateNormal]; [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; self.titleLabel.textAlignment = NSTextAlignmentCenter; self.enabled = NO; } return self;}+ (instancetype)buttonWithProduct:(LDProduct *)product{ return [[self alloc] initWithProduct:product];}