自定义视图:系统标准UI之外, 组合形成出的新的视图。 即创建一个类继承于UIView 或者其他的视图,在自定义类中创建其视图,这样就会形成一个新的自定义视图。
自定义视图的优点:
iOS提供了很多UI组件,借助它们我们可以实现不同的功能。尽管如此,实际开发中,我们还需自定义视图。积累自己的代码库,方便我们的开发。 封装的视图,能像系统UI控件一样, 于别的项目中,能降低开发成本,提高开发效率。
质量代码的特点:可复制性 ,可移植,精炼等。( 内聚,低耦合)
自定义视图步骤:
1、创建一个LUIView类
@interface LTView : UIView
//自定义视图第一步:明确该视图内部有什么控件,并且将所有控件声明成属性
@property (nonatomic, retain) UILabel *label;
@property (nonatomic, retain) UITextField *textField;
//自定义初始化方法
- (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text textColor:(UIColor *)textColor font:(UIFont *)font borderStyle:(UITextBorderStyle)borderStyle placeholder:(NSString *)placeholder secureTextEntry:(BOOL)secureTextEntry keyboardType:(UIKeyboardType)keyboardType;
此时的LTView就变成了一个具有label和TextField的视图了。
//重写LTView继承自UIView的布局方法,来创建子视图,并且添加子视图
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
//用参数中的frame(LTView视图整体的frame)来表示内部控件的frame
//LTView的宽和高
CGFloat totalWidth = frame.size.width;
CGFloat totalHeight = frame.size.height;
//label的宽和高
CGFloat labelWidth = (totalWidth - 15) / 3;
CGFloat labelHeight = totalHeight - 4;
//textField的宽和高
CGFloat textFieldWidth = 2 * labelWidth;
CGFloat textFieldHeight = labelHeight;
_label = [[UILabel alloc] initWithFrame:CGRectMake(5, 2, labelWidth, labelHeight)];
// _label.backgroundColor = [UIColor redColor];
[self addSubview:_label];
_textField = [[UITextField alloc] initWithFrame:CGRectMake(10 + labelWidth, 2, textFieldWidth, textFieldHeight)];
// _textField.backgroundColor = [UIColor blueColor];
[self addSubview:_textField];
}
return self;
}
//自定义初始化方法
- (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text textColor:(UIColor *)textColor font:(UIFont *)font borderStyle:(UITextBorderStyle)borderStyle placeholder:(NSString *)placeholder secureTextEntry:(BOOL)secureTextEntry keyboardType:(UIKeyboardType)keyboardType {
self = [self initWithFrame:frame];
if (self) {
self.label.text = text;
self.label.textColor = textColor;
self.label.font = font;
self.textField.borderStyle = borderStyle;
self.textField.placeholder = placeholder;
self.textField.secureTextEntry = secureTextEntry;
self.textField.keyboardType = keyboardType;
}
return self;
}
自定义cell
UITableView中系统的Cell共提供了四种默认样式, 分别是:
UITableViewCellStyleDefault
UITableViewCellStyleValue1
UITableViewCellStyleValue2
UITableViewCellStyleSubtitle
但是在实际使用过程中,Cell样式的布局上千差万别, 系统提供的cell满 不了复杂的样式,因此: 定义Cell 和 定义视图 样, 创建 种符合我们需求的Cell并且使用这个Cell。
自定义Cell步骤:
创建一个类继承于UITableViewCell。 实现UITableViewCell的初始化方法:
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 。 确保所有的你想添加的视图都在自定义Cell的初始化方法中创建,由于UITableView的重用机制, 这个Cell在第一次创建成功并用于下一次显示的时候,不会再走初始化方法,这样可以避免视图的重复创建。 在Cell视图创建成功后,将视图设置为属性,类似于 UITableViewCell所自带的textLabel和detailTextLabel属性。方便于在UITableView的协议中给自定义视图赋值。
一、将所有cell要显示的子视图控件声明成属性
二、重写cell的初始化方法,frame给定为0,将控件添加到cell上面进行显示,一定要注意使用self.contentView添加
三、重写layoutSubviews方法,给定内部控件的具体位置
四、导入模型,将模型与cell绑定,声明模型属性
五、重写模型属性的setter方法,内部使用模型为内部控件赋值
六、内存管理
@property (nonatomic, retain) UIImageView *headerImageView;//头像
@property (nonatomic, retain) UILabel *nameLabel;//姓名
@property (nonatomic, retain) UILabel *genderLabel;//性别
@property (nonatomic, retain) UILabel *ageLabel;//年龄
//在cell内部绑定一个模型属性
@property (nonatomic, retain) Student *stu;
//重写cell的初始化方法。
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_headerImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
_headerImageView.backgroundColor = [UIColor redColor];
//自定义cell内部添加子视图 不能使用self,应该是使用self.contentView
[self.contentView addSubview:_headerImageView];
_nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_nameLabel.backgroundColor = [UIColor yellowColor];
[self.contentView addSubview:_nameLabel];
_genderLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_genderLabel.backgroundColor = [UIColor greenColor];
[self.contentView addSubview:_genderLabel];
_ageLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_ageLabel.backgroundColor = [UIColor blueColor];
[self.contentView addSubview:_ageLabel];
}
return self;
}
//重写模型的setter方法。完成赋值
- (void)setStu:(Student *)stu {
if (_stu != stu) {
[_stu release];
_stu = [stu retain];
//为内部控件进行赋值
_headerImageView.image = [UIImage imageNamed:_stu.picture];
_nameLabel.text = _stu.name;
_genderLabel.text = _stu.gender;
_ageLabel.text = _stu.age;
}
}
- (void)layoutSubviews {
[super layoutSubviews];
_headerImageView.frame = CGRectMake(5, 5, 50, 80);
_nameLabel.frame = CGRectMake(65, 5, 100, 20);
_genderLabel.frame = CGRectMake(65, 35, 100, 20);
_ageLabel.frame = CGRectMake(65, 65, 100, 20);
}
@end