一、Plist文件
属性列表文件,是一个xml文档
1.能直接存储数据类型:Dictionary、Array、Boolean、Data、Date、Number、String
2.其他类型要存储,必须先进行转化再存储,比如如果把UIView对象存入数组再存入Plist文件,虽然不报错,但是是错误的。
3.NSBundle
(1).一个NSBundle对象对应一个资源包(图片、音频、视频、plist等文件)
(2).NSBundle的作用:用来访问与之对应的资源包内部的文件,可以用来获得文件的全路径
(3).项目中添加的资源都会被添加到主资源包中
(4).[NSBundle mainBundle]关联的就是项目的主资源包
4.Plist文件的解析
----------方式一
NSBundle *bundle = [NSBundle mainBundle];
//获取Plist在资源包里的全路径
NSString *path = [bundle pathForResource:@"Property List" ofType:@"plist"];
//凡是参数名为File,传递的都是文件的全路径
NSArray *arr = [NSArray arrayWithContentsOfFile:path];
NSLog(@"%@",arr);
----------方式二
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:@"Property List.plist" ofType:nil];
NSArray *arr = [NSArray arrayWithContentsOfFile:path];
NSLog(@"%@",arr);
二、HUD
1.其他说法:指示器、遮盖、蒙板
2.作用:用于显示提示信息
3.半透明HUD的做法:背景色设置为半透明颜色
4.定时任务
//方法1:performSelector
// 1.5s后自动调用self的hideHUD方法
[self performSelector:@selector(hideHUD) withObject:nil afterDelay:1.5];
//方法2:GCD
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 1.5s后自动执行这个block里面的代码
self.hud.alpha = 0.0;
});
//方法3:NSTimer
// 1.5s后自动调用self的hideHUD方法;repeats如果为YES,意味着每隔1.5s都会调用一次self的hidHUD方法
[NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(hideHUD) userInfo:nil repeats:NO];
三、字典转模型
1.字典设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编辑器没有智能提示,手敲字符串key,key容易写错,如果Key写错了,编译器不会有任何警告和报错,排错困难。
2.模型其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业;模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,保证了数据的正确性;使用模型访问属性时,编译器会提供一系列的提示,提高编码效率。
3.设计模型时,属性名一般于各个KEY名一致,提高阅读性。
4.代码举例
----------模型的.h文件
#import <Foundation/Foundation.h>
@interface SSData : NSObject
/** 图片*/
@property (nonatomic,strong) NSString *icon;
/** 文字*/
@property (nonatomic,strong) NSString *name;
+ (instancetype)ssdataWithIcon:(NSString *)icon name:(NSString *)name;
- (instancetype)initWithIcon:(NSString *)icon name:(NSString *)name;
@end
----------模型的.m文件
#import "SSData.h"
@implementation SSData
+ (instancetype)ssdataWithIcon:(NSString *)icon name:(NSString *)name {
return [[self alloc] initWithIcon:icon name:name];
}
- (instancetype)initWithIcon:(NSString *)icon name:(NSString *)name {
//字典转模型的过程最好封装在模型内部
if (self = [super init]) {
_icon = icon;
_name = name;
}
return self;
}
@end
四、纯代码封装View
1.如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心
2.外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据
3.封装控件的基本步骤
(1).在initWithFrame:方法中添加子控件,提供便利构造方法;调用init方法时,系统会自动调用initWithFrame:方法;一般不通过重写init方法来创建子控件。
(2).在layoutSubviews方法中设置子控件的frame(一定要调用super的layoutSubviews);对象本身的Frame发生变化,就会调用layoutSubviews方法。注意:不能在init方法中设置子控件的Frame,因为父控件的Frame初始为0,子控件调用了为0的Frame就会看不见子控件。
(3).增加模型的属性,重写模型属性set方法,在set方法中给内部的子控件设置对应的数据
4.举例子
----------封装View的.h文件
#import <UIKit/UIKit.h>
@class SSData;
@interface SSShowView : UIView
/** 商品模型,用于接收商品的信息,给子控件赋值*/
@property (nonatomic,strong) SSData *showData;
//构造工厂方法
+ (instancetype)showView;
@end
----------封装View的.m文件,方式一
#import "SSShowView.h"
#import "SSData.h"
@interface SSShowView()
/** 图片*/
@property (nonatomic,strong) UIImageView *iconView;
/** 名称*/
@property (nonatomic,strong) UILabel *nameLable;
@end
@implementation SSShowView
//构造工厂方法
+ (instancetype)showView {
return [[self alloc] init];
}
//用于创建子控件
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
//创建图片视图
UIImageView *iconView = [[UIImageView alloc] init];
[self addSubview:iconView];
self.iconView = iconView;
//创建文本标签
UILabel *nameLable = [[UILabel alloc] init];
[self addSubview:nameLable];
self.nameLable = nameLable;
}
return self;
}
//用于设置子控件的Frame
-(void)layoutSubviews {
[super layoutSubviews];
CGFloat showW = self.frame.size.width;
CGFloat showH = self.frame.size.height;
self.iconView.frame = CGRectMake(0, 0, showW, showW);
self.nameLable.frame = CGRectMake(0, showW, showW, showH - showW);
}
//用于给子控件赋值
- (void)setShowData:(SSData *)showData {
_showData = showData;
self.iconView.image = [UIImage imageNamed:showData.icon];
self.nameLable.text = showData.name;
}
@end
----------封装View的.m文件,方式二
#import "SSShowView.h"
#import "SSData.h"
@interface SSShowView()
/** 图片*/
@property (nonatomic,strong) UIImageView *iconView;
/** 名称*/
@property (nonatomic,strong) UILabel *nameLable;
@end
@implementation SSShowView
//构造工厂方法
+ (instancetype)showView {
return [[self alloc] init];
}
//在get方法中创建控件,懒加载
- (UIImageView *)iconView {
if (_iconView == nil) {
UIImageView *iconView = [[UIImageView alloc] init];
[self addSubview:iconView];
_iconView = iconView;
}
return _iconView;
}
//在get方法中创建控件,懒加载
- (UILabel *)nameLable {
if (_nameLable == nil) {
UILabel *nameLable = [[UILabel alloc] init];
[self addSubview:nameLable];
_nameLable = nameLable;
}
return _nameLable;
}
//用于设置子控件的Frame
-(void)layoutSubviews {
[super layoutSubviews];
CGFloat showW = self.frame.size.width;
CGFloat showH = self.frame.size.height;
self.iconView.frame = CGRectMake(0, 0, showW, showW);
self.nameLable.frame = CGRectMake(0, showW, showW, showH - showW);
}
//用于给子控件赋值
- (void)setShowData:(SSData *)showData {
_showData = showData;
self.iconView.image = [UIImage imageNamed:showData.icon];
self.nameLable.text = showData.name;
}
@end
----------封装后的调用
//创建一个显示商品的UIView
SSShowView *smallView = [SSShowView showView];
smallView.frame = smallViewFrame;
[self.showView addSubview:smallView];
//设置数据
smallView.showData = self.shopsArray[index];
五、XIB封装子控件
1.XIB可以自定义控件,即在XIB中,可以用View封装几个小的控件为一个整体
2.创建XIB
(1).选择View图标,XIB里面会自动创建一个View
(2).选择Empty图标,创建的XIB是空的
(3).设置XIB名字,名字应该与类名(要与所属的类)一致,点击哪个类,系统就会自动取与之对应的名字
3.在XIB里面创建View后设置大小,和去掉电池图标
4.把子控件拖入后,修改属性
5.设置XIB所属的类
6.子控件与类的属性连线
7.代码如下
----------XIB所属的类 .h文件
#import <UIKit/UIKit.h>
@class SSData;
@interface SSShowView : UIView
/** 商品模型,用于接收商品的信息,给子控件赋值*/
@property (nonatomic,strong) SSData *showData;
//创建View
+ (instancetype)showView;
//用于创建自定义的View,然后给其子控件赋值
+ (instancetype)showViewWithShowData:(SSData *)data;
@end
----------XIB所属类 .m文件
#import "SSShowView.h"
#import "SSData.h"
@interface SSShowView()
/** 图片*/
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
/** 名称*/
@property (weak, nonatomic) IBOutlet UILabel *nameLable;
@end
@implementation SSShowView
//创建View
+ (instancetype)showView {
//解析XIB文件
SSShowView *showView = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] firstObject];
return showView;
}
//用于创建自定义的View,然后给其子控件赋值
+ (instancetype)showViewWithShowData:(SSData *)data {
SSShowView *show = [self showView];
show.showData = data;
return show;
}
//重写set方法,用于给子控件赋值
- (void)setShowData:(SSData *)showData {
_showData = showData;
self.imageView.image = [UIImage imageNamed:showData.icon];
self.nameLable.text = showData.name;
NSLog(@"%@",showData.icon);
}
@end
----------封装后的调用,注意:调用的时候与纯代码封装View后的调用完全一样,所以用XIB封装更加简洁!
//创建一个显示商品的UIView
SSShowView *smallView = [SSShowView showView];
smallView.frame = smallViewFrame;
[self.showView addSubview:smallView];
//设置数据
smallView.showData = self.shopsArray[index];
六、一个控件看不见有哪些可能?
- 宽度或者高度其实为0
- 位置不对(比如是个负数或者超大的数,已经超出屏幕)
- hidden == YES
- alpha <= 0.01
- 没有设置背景色、没有设置内容
- 可能是文字颜色和背景色一样