
功能分析
(1)左下角4个方向按钮,控制头像按钮的位置 (2)右下角分别是放大、缩小按钮,控制头像的尺寸 (3)头像按钮既有背景图片,又有文字步骤分析
(1)搭建UI界面 (2)监听按钮点击 (3)修改头像按钮的属性来调整位置和尺寸 1、先准备素材 Xcode5之后,都是把图片素材,统一放到
点击,拖拽即可
2、进行 UI 设计
按钮的点击状态
在 ios7之后,出现的一个设置,在属性查看器里,type 下默认选择的是 system,就是让系统去改变,如果改为 custom,就是自定义,可以自己定义变化,而不让系统去帮我们改变。
比如:设计一个图片式的按钮之后,点的刹那是高亮的,松开就是恢复到原样。
点击之前的样子
点击下去的样子,按钮显式高亮状态,松开之后,回复到原样
把属性 type 改为 custom ,进行自定义的修改,同时修改state config 选项,也就是要修改 高亮状态,还有同时修改文本标题,文本颜色,按钮的背景等。如下:
运行,再次点击下去,高亮就不是以前那样了,改变为:
松开之后,恢复原样。
设置上下左右四个方向键(当相同的控件很多的时候,使用复制,粘贴,比较省事),同时记得修改高亮状态下背景,点击下,变为绿色。
连线,进行监听
先设置 up 方向,学习修改控件属性的过程三步骤:
@PRoperty(nonatomic) CGRect frame;控件所在矩形框在父控件中的位置和尺寸(以父控件的左上角为坐标原点),可以定义位置(origin),大小(size),frame 本身是结构体,里面的成员都是结构体属性的成员。
1 //
2 // ViewController.m
3 // 按钮使用1
4 //
5 // Created by 大帅 on 15-2-28.
6 // Copyright (c) 2015年 dashuai. All rights reserved.
7 //
8
9 #import "ViewController.h"
10
11 @interface ViewController ()
12 @property (weak, nonatomic) IBOutlet UIButton *HeadImageView;
13
14 @end
15
16 @implementation ViewController
17 //up方向键进行连线
18 -(IBAction)move
19 {
20 //使用 frame 修改headimageview 的位置
21 //注意,在 oc 中,不可以直接修改"对象"的"结构体属性"的"成员"
22 //frame 是结构体,里面的 orign 等等都是结构体
23 //并且,这里 orign 是 frame 的成员,不能直接去修改,如下写法在 oc 是不对的
24
25 // self.HeadImageView.frame.origin.y = self.HeadImageView.frame.origin.y - 10;
26
27 //应该间接修改
28 //1、取出结构体属性
29 CGRect rect = self.HeadImageView.frame;
30 //2、修改结构体里面的成员,此时取出之后,frame已经不是对象了
31 rect.origin.y -= 20;
32 //3、把值赋回来,就是这三个步骤。必须有这步。
33 self.HeadImageView.frame = rect;
34 }
35
36 @end
三步骤:取出结构体属性,修改结构体的成员,把值赋回来。
好嘞,熟悉之后,重新连接四个控件,把 move 对象方法修改为带参数
-(IBAction)move:(UIButton *)button

删掉旧的连接,重新连接新的 move 方法,点击上下左右,都可以调用 move 方法,只要能区分就行了。使用 tag:
@property(nonatomic) NSInteger tag;
控件的ID(标识),父控件可以通过tag来找到对应的子控件,在属性查看器里,依次设置修改即可让控件 button 通过 tag 的值,找到不同的子控件。
button.tag
魔法数字的概念(避免硬编码)
术语:其他程序员看到后,不能见名知意的数字,不是好习惯,在程序开发中需要避免出现魔法数字(Magic Number),在 oc ,可以使用枚举类型,宏定义来避免在程序中出现魔法数字。 在其它一些编程语言里,也类似,要避免硬编码。
1> 枚举类型实质上就是一个整数,其作用就是用来替代魔法数字
2> 枚举类型中,指定了第一个整数之后,后面的数字会递增
记住,定死的一些东西,统一放到程序主体的上面,统一定义,避免硬编码
1 #import "ViewController.h"
2
3 //10是 up,11是 down,12是 left,13是 right
4 //枚举,
5 typedef enum
6 {
7 kMovingDirTop = 10,
8 kMovingDirBottom,
9 kMovingDirLeft,
10 kMovingDirRight
11 } kMovingDir;
12 //宏定义 偏移量
13 #define kMovingDelta 20
14
15 @interface ViewController ()
16 @property (weak, nonatomic) IBOutlet UIButton *HeadImageView;
17
18 @end
19
20 @implementation ViewController
21 //方向键进行连线
22 -(IBAction)move:(UIButton *)button
23 {
24 //1、取出结构体属性
25 CGRect rect = self.HeadImageView.frame;
26 //2、修改结构体里面的成员,此时取出之后,frame已经不是对象了
27 switch (button.tag) {
28 case kMovingDirTop:
29 rect.origin.y -= kMovingDelta;
30 break;
31 case kMovingDirBottom:
32 rect.origin.y += kMovingDelta;
33 break;
34 case kMovingDirLeft:
35 rect.origin.x -= kMovingDelta;
36 break;
37 case kMovingDirRight:
38 rect.origin.x += kMovingDelta;
39 break;
40 default:
41 break;
42 }
43 //3、把值赋回来,就是这三个步骤。必须有这步。
44 self.HeadImageView.frame = rect;
45 }
效果如下 :

//该位置是 orign,改大小是 size属性
- (IBAction)zoom:(UIButton *)button {
CGRect rect = self.HeadImageView.frame;
//如果为1,则是放大,否则缩小
if (button.tag) {
rect.size.height += kMovingDelta;
rect.size.width += kMovingDelta;
} else {
rect.size.height -= kMovingDelta;
rect.size.width -= kMovingDelta;
}
self.HeadImageView.frame = rect;
}
oc 从 Xcode4.6开始,有了一个自动布局系统 autolayout,由于这个系统,一些设置和改变,就不会起效,苹果规定,当使用了自动布局系统之后,就不要在使用代码控制位置了。在程序运行中,每个控件的大小和位置,都应该交给自动布局系统来决定。所以不会发生改变。
把它勾掉,就可以起效了
那么问题来了,缩小放大的时候原点不变。因为改变的是 size 属性,没有改变原点位置,记住:
1> frame可以修改对象的位置和尺寸
2> bounds可以修改对象的尺寸(这里使用 bounds 可以实现四周的增大缩小,而不是原点不变了,bounds 的宽高和边框是相等的!先记住。)
3> center可以修改对象的位置
- (IBAction)zoom:(UIButton *)button {
CGRect rect = self.HeadImageView.bounds;
//如果为1,则是放大,否则缩小
if (button.tag) {
rect.size.height += kMovingDelta;
rect.size.width += kMovingDelta;
} else {
rect.size.height -= kMovingDelta;
rect.size.width -= kMovingDelta;
}
self.HeadImageView.bounds = rect;
}
这样修改之后效果就是四周的变大缩小,而不是原点不变

介绍一个动画效果:首尾式动画效果代码实现
// beginAnimations表示此后的代码要“参与到”动画中 [UIView beginAnimations:nil context:nil]; // setAnimationDuration用来指定动画持续时间 [UIView setAnimationDuration:2.0]; self.headImageView.bounds = rect; ...... // commitAnimations,将beginAnimation之后的所有动画提交并生成动画 [UIView commitAnimations];
有了动画效果之后,是先修改宽和高,再修改中心点,可以设置持续的时间。不加动画之前,看不出来,很快。
//该位置是 orign,改大小是 size属性
- (IBAction)zoom:(UIButton *)button {
CGRect rect = self.HeadImageView.bounds;
//如果为1,则是放大,否则缩小
if (button.tag) {
rect.size.height += kMovingDelta;
rect.size.width += kMovingDelta;
} else {
rect.size.height -= kMovingDelta;
rect.size.width -= kMovingDelta;
}
//动画开始,以后的代码全部参与到动画里
[UIView beginAnimations:nil context:nil];
//设置动画持续时间2秒
[UIView setAnimationDuration:2.0];
self.HeadImageView.bounds = rect;
//oc里透明度,1是完全看见,0是完全看不见,变变化大小,边消失的效果
self.HeadImageView.alpha = 0;
//提交,并生成动画
[UIView commitAnimations];
}
也可以使用 center 属性改变对象位置(只能改变位置,不能改变大小,而 orign 可以改变大小和位置)
关于 git

点击上图中的标志,可以查看和上次提交的版本不一样的地方,也就是修改的情况的查看
通过此操作,来实现代码的版本提交
如下,文件后面有 m 表示这个文件被修改过。

//应该间接修改
//1、取出结构体属性
CGRect rect = self.HeadImageView.frame;
//2、修改结构体里面的成员,此时取出之后,frame已经不是对象了
rect.origin.y -= 20;
//3、把值赋回来,就是这三个步骤。必须有这步。
self.HeadImageView.frame = rect;
如果没有第三步,则无法成功修改属性,因为 rect 不是指针,地址和 frame 的地址不一样,修改完毕,必须重新赋值回去,才能生效。
修改结构体属性的成员方法如下:
1> 使用临时变量记录对象的结构体属性
2> 修改临时变量的属性
3> 将临时变量重新设置给对象的结构体属性
6、同一个项目中,尽量不要重复的代码去完成类似的功能,不要经常性的复制一样的代码。造成很大冗余。要尽量精简。
7、Xcode5之后,经常会有一些莫名其妙的问题出现,解决不了,可以尝试退出重新打开,再看看。 8、在 oc 中,不可以直接修改"对象"的"结构体属性"的"成员",要三部曲间接修改。 9、switch 语句中的default 当变量的取值不在分支里任何一个case的情况下,语句要做的处理,其实也是一种case,只不过就是指“除了指定的几个case以外的其他情况”,是一个中安全的编程方式。 10、注意魔法数字的问题避免,枚举的作用,宏定义 11、图片素材统一放到images.xcassets里面,从Xcode5开始,图片资源都放到Images.xcassets中进行管理 12、注意三个属性的用处1> frame可以修改对象的位置和尺寸
2> bounds可以修改对象的尺寸
3> center可以修改对象的位置
13、首尾式动画效果,透明度的设置alpha,记住苹果里,动画是廉价的,很容易就能实现非常绚丽的效果。
14、git 入门
15、如果发现通过代码无法修改控件的位置或者尺寸时,应该去掉storyboard里面的autolayout功能,这是自iOS6开始出现的特性,顾名思义,autolayout是用来自动布局的,用来束缚控件的位置和尺寸。去掉这个功能,控件的位置和尺寸就不再有一些固定的束缚。
16、UIButton的状态
normal(普通状态) 默认情况(Default) 对应的枚举常量:UIControlStateNormal highlighted(高亮状态) 按钮被按下去的时候(手指还未松开) 对应的枚举常量:UIControlStateHighlighted disabled(失效状态,不可用状态) 如果enabled属性为NO,就是处于disable状态,代表按钮不可以被点击 对应的枚举常量:UIControlStateDisabled 17、设置按钮在不同状态下的背景图片时,为了保证高亮状态下的图片正常显示,必须设置按钮的type为custom(自定义)