1、IBAction
1> 能保证方法可以连线
2> 相当于void
2、IBOutlet:能保证属性可以连线
3、常见错误
[setValue:forUndefinedKey:]: this class is not key value coding
错误原因:连线出问题了
4、Xcode5开始的一些建议
把用于连线的一些方法和属性声明在.m文件的类扩展中
5、frame\center\bounds
1> frame:能修改位置和尺寸
2> center:能修改位置
3> bounds:能修改尺寸(x\y一般都是0)
6、 OC语法规定:不许直接修改对象结构体属性的成员
self.head.frame.origin.y -= 10;
这种写法是错误的,一般使用下面三步定义中间变量赋值修改
1> CGRect tempFrame = self.head.frame.origin.y
2> tempFrame.origin.y -= 10;
3> self.head.frame = tempFrame
7、 •简易动画大致有2种方式:
Ø头尾式
[UIView beginAnimations:nil context:nil];
/** 需要执行动画的代码 **/
[UIView commitAnimations];
Ø
Block
式
[UIView animateWithDuration:0.5 animations:^{
/**需要执行动画的代码 **/
}];
8、修改控件的位置和尺寸
•通过以下属性可以修改控件的位置
Ø
frame
.
origin
Ø
center
•
通过以下属性可以修改控
件的尺寸
Ø
frame.size
Ø
bounds.size
9、
transform
属性
•
利用
transform
属性可以修改控件的位移(位置)、缩放、旋转
•
创建一个
transform
属性
Ø
CGAffineTransform
CGAffineTransformMakeTranslation(
CGFloat
tx
,
CGFloat
ty
)
;
Ø
CGAffineTransform
CGAffineTransformMakeScale(
CGFloat
sx,
CGFloat
sy
);
Ø
CGAffineTransform
CGAffineTransformMakeRotation(
CGFloat
angle
)
(angle是弧度制,并不是角度制)
•
在某个
transform
的基础上进行叠加
Ø
CGAffineTransform
CGAffineTransformTranslate(
CGAffineTransform
t
,
CGFloat
tx,
CGFloat
ty
);
Ø
CGAffineTransform
CGAffineTransformScale(
CGAffineTransform
t
,
CGFloat
sx,
CGFloat
sy
);
Ø
CGAffineTransform
CGAffineTransformRotate(
CGAffineTransform
t
,
CGFloat
angle
);
•
清空之前设置的
transform
属性
view.transform = CGAffineTransformIdentity;
10、
UIButton
和
UIImageView
•
相同点:都能显示图片
•
不同点
Ø
UIButton
默认情况就能监听点击事件,而
UIImageView
默认情况下不能
Ø
UIButton
可以在不同状态下显示不同的图片
Ø
UIButton
既能显示文字,又能显示图片
•
如何选择
Ø
UIButton
:需要显示图片,点击图片后需要做一些特定的操作
Ø
UIImageView
:仅仅需要显示图片,点击图片后不需要做任何事情
11、
NSArray
和
NSDictionary
的使用
•
当图片内容非常多时,“根据
index
来设置内容”的代码就不具备扩展性,要经常改动
•
为了改变现状,可以考虑讲图片数据线保存到一个数组中,数组中有序地放着很多字典,一个字典代表一张图片数据,包含了图片名、图片描述
@property (strong, nonatomic) NSArray*images;
•
由于只需要初始化一次图片数据,因此放在
get
方法中初始化
•
将属性放在get方法中初始化的方式,称为“懒加载
”
\”
延迟加载
”
12、plist文件的使用
•
直接将数据直接写在代码里面,不是一种合理的做法。如果数据经常改,就要经常翻开对应的代码进行修改,造成代码扩展性低
•
因此,可以考虑将经常变的数据放在文件中进行存储,程序启动后从文件中读取最新的数据。如果要变动数据,直接修改数据文件即可,不用修改代码
•
一般可以使用属性列表文件存储
NSArray
或者
NSDictionary
之类的数据,这种属性列表文件的扩展名是
plist
,因此也成为“
Plist
文件”
•
接下来通过代码来解析
Plist
文件中的数据
Ø
获得
Plist
文件的全路径
NSBundle*bundle = [NSBundle mainBundle];
NSString*path = [bundle pathForResource:@"imageData" ofType:@"plist"];
Ø
加载
plist
文件
_images = [NSArray arrayWithContentsOfFile:path];
- (NSArray*)images
{
if (_images == nil) {
NSBundle*bundle = [NSBundle mainBundle];
NSString*path = [bundle pathForResource:@"imageData" ofType:@"plist"];
_images = [NSArray arrayWithContentsOfFile:path];
}
return _images;
}
13、UIImageView
帧动画相关属性和方法(注意:帧动画启动方法一定要放在设置动画后面,不然程序会出问题,本人亲测,不信邪的小伙伴阔以试试)
•
@property
(
nonatomic
,
copy
)
NSArray
*animationImages;
Ø
需要播放的序列帧图片数组(里面都是
UIImage
对象,会按顺序显示里面的图片)
•
@
property
(
nonatomic
)
NSTimeInterval
animationDuration
;
Ø
帧动画的持续时间
•
@
property
(
nonatomic
)
NSInteger
animationRepeatCount
;
Ø
帧动画的执行次数(默认是无限循环)
•
- (
void
)startAnimating
;
Ø
开始执行帧动画
•
- (
void
)stopAnimating
;
Ø
停止执行帧动画
•
- (
BOOL
)isAnimating
;
Ø
是否正在执行帧动画
14、UIImage
的
2
种加载方式
•
方式一:有缓存(图片所占用的内存会一直停留在程序中),适合图片较少的时候使用,
当你把图片放在
Images.xcassets
就只能通过
imageNamed
加载
Ø
+ (
UIImage
*)imageNamed:(
NSString
*)name
;
Ø
name
是图片的文件名
•
方式二:无缓存(图片所占用的内存会在一些特定操作后被清除)
Ø
+ (
UIImage
*)imageWithContentsOfFile:(
NSString
*)
path
Ø
- (
id
)initWithContentsOfFile:(
NSString
*)path
;
Ø
path
是图片的全路径
15、清空动画结束后的内存
// 清空图片数组animationImages的时间为动画执行完毕后0.1s
CGFloat delay = self.imageView.animationDuration + 0.1;
// 让self.imageView延迟 delay秒 执行setAnimationImages:方法来清空图片数组animationImages
[self.imageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:delay];
相当于调用了animationImages的setter方法:self.imageView.animationImages = nil
16、重复代码的封装抽取
•
当一份代码重复出现在程序的多处地方,就会造成程序又臭又长,当这份代码的结构要修改时,每一处出现这份代码的地方都得修改,导致程序的扩展性很差
•
因此,要将重复出现的代码抽取到某个方法中,在需要这份代码的地方调用方法即可
•
抽取代码的思路
Ø
将相同的代码放到一个方法中
Ø
将不同的值当做方法参数传进来