#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIButton *button;
/*
//实现点击向上的方法
- (IBAction)up:(id)sender;
//实现点击向下的方法
- (IBAction)lower:(id)sender;
//实现点击向右的方法
- (IBAction)right:(id)sender;
//实现点击向左的方法
- (IBAction)left:(id)sender;
*/
//上下左右移动的方法实现 利用tag,和if或者switch条件语句
- (IBAction)run:(id)sender;
//旋转方法的实现 利用tag 利用if语句
- (IBAction)rotate:(id)sender;
//伸缩的方法实现 利用tag 利用三目运算
- (IBAction)telescopic:(id)sender;
@end
#import "ViewController.h"
#define kdelta 20
@interface ViewController ()
@end
@implementation ViewController
/*
#pragma mark 向上走的实现方法
- (IBAction)up:(id)sender {
//添加动画,是为了让效果更好看,用法就是把这个方法上下包住
//动画是一个UIView的类方法,[UIView beginAnimations:(NSString *) context:(void *)]; 在大部分情况下,(NSString *) 和(void *)都直接为空
//动画开始,是慢慢的执行
[UIView beginAnimations:nil context:nil];
//设置动画的执行时间,也是一个UIView类方(是double类型,所以有小数点)
[UIView setAnimationDuration:2.0]; // 时间是以秒为单位。这个类方法的意思就是y值,点击向上一次的时间是2秒,这个可以随便修改
//两种获得button这个属性的方法,为什么要获得button能,因为最后是要控制这个button,所以要获得它
//_button;// 这个是获得button第一种方法
//因为要控制button向上走,所以是控制y值(y值是向上向下,x值是向左向右),而这个x和y值都是在frame属性中,frame是UIButton中得属性,而UIButton是继承UIView
//self.button;// 这个是获得button第二种方法
//这个是修改y值,因为frame中得origin是控制坐标的(x,y),size是控制宽高的(height,width), 向上是减等于,向下是加等于,所以要修改y的值就用下面这个方法
//self.button.frame.origin.y -= 5; // 这样写法虽然看似没有错,但是oc语法有规定,不能直接修改某个对象中结构体的属性成员,所以也不能这样写self.button.frame.origin.y -=10;
//1.先取出frame,但是frame属于CGRect,所以定义一个CGRect的变量frame,把self.button.frame; 赋值给变量frame
CGRect frame = self.button.frame; //这个语句是先把self.button.frame拿出来赋值给一个新的frame,这个frame和self.button.frame;中得frame没有关系
//2.修改y值
//frame.origin.y = frame.origin.y - 20;//这个语句有一种简单的方法,
//if(tag == 1){
frame.origin.y -= 20;
//}
//3.重新赋值按钮的frame,虽然frame.origin.y -= 5;这个是每点击一次y值减少5,但是只是减少的CGRect frame,和self.button.frame;没有关系,所以必须得把CGRect frame重新赋值回去
self.button.frame = frame; // 这样就能够实现点击向上按钮一次就向上走一次。
//动画结束,也是UIView类方法,提交动画或者执行动画
[UIView commitAnimations];
}
#pragma mark 向下走的实现方法
- (IBAction)lower:(id)sender {
//实现动画效果
[ UIView beginAnimations:nil context:nil];
//设置动画执行时间
[UIView setAnimationDuration:2.0];
//1.先取出frame
CGRect frame = _button.frame;
// 向下走是y值加等于 (+=) 一定要连起来写
frame.origin.y += 20;
//把frame的值从新赋值给_button.frame
_button.frame = frame;
//设置动画结束
[UIView commitAnimations];
}
#pragma mark 向右走的实现方法
- (IBAction)right:(id)sender {
//实现动画
[ UIView beginAnimations:nil context:nil];
//设置动画执行时间
[UIView setAnimationDuration:2.0];
// 获取frame;
CGRect frame = self.button.frame;
//修改x值,向右走是加等于
frame.origin.x += 20;
//把frame的值赋值给self.button.frame;
self.button.frame = frame;
//设置动画结束
[UIView commitAnimations];
}
#pragma mark 向左走的实现方法
- (IBAction)left:(id)sender {
//实现动画
[ UIView beginAnimations:nil context:nil];
//设置动画执行时间
[UIView setAnimationDuration:2.0];
// 获取frame的值
CGRect frame = _button.frame;
//修改x的值
frame.origin.x -= 20;
// 把frame在赋值给 _button.frame
_button.frame = frame;
//设置动画结束
[UIView commitAnimations];
}
*/
//上下左右的的效果
- (IBAction)run:(id)sender {
//(id)sender,是传一个参数,点击那个按钮,就传那个参数
//实现动画
[ UIView beginAnimations:nil context:nil];
//设置动画执行时间
[UIView setAnimationDuration:2.0];
// 获取frame的值
CGRect frame = _button.frame;
// 控制上下左右(x,y)的值,可以用if else语句,也可以用switch语句
// if else 语句的用法
//获得参数的值,不能用点语法sender.tag,要用get语法
/*
if([sender tag] == 1){
frame.origin.y -= 20;
}else if([sender tag] == 2){
frame.origin.x += 20;
}else if([sender tag] == 3){
frame.origin.y += 20;
}else if([sender tag] == 4){
frame.origin.y -= 20;
}
// 这个20也可以拿出来,两种方式,宏定义和定义变量,这样做得目的是,如果要修改这个值,可以一步就修改了,不用在一个一个修改。宏定义要卸载引用文件的位置,可以控制整个文件,一般都写宏定义,
//CGFloat delta = 20;
//可以把[sender tag]提前出来,设置为变量
NSInteger tag = [sender tag];
if(tag == 1){
frame.origin.y -= kdelta;
}else if(tag == 2){
frame.origin.x += kdelta;
}else if(tag == 3){
frame.origin.y += kdelta;
}else if(tag == 4){
frame.origin.y -= kdelta;
}
*/
//switch语法
switch([sender tag]){
case 1:
frame.origin.y -= kdelta;
break;
case 2:
frame.origin.x += kdelta;
break;
case 3:
frame.origin.y += kdelta;
break;
case 4:
frame.origin.x -= kdelta;
break;
default:
break;
}
// 把frame在赋值给 _button.frame
_button.frame = frame;
//设置动画结束
[UIView commitAnimations];
}
#pragma mark 左右旋转
// 左右旋转的效果(封装),旋转是形变属性-transform
- (IBAction)rotate:(id)sender {
//旋转角度用M_PI这个宏定义,PI=π,也就是180°,M_PI_4这个代表4分之PI = 45°,M_PI_2这个代表2分之PI = 90°。M_2_PI这个表示PI的两倍=360°。如果要实现某个旋转功能,就是表示增加或者减少这个°(度数),旋转就是向右(顺时针 +)或者向左(逆时针 -) 比如想要某个向左旋转45°
//因为形变的属性是transform,所以要用按钮来活动这个属性,两种方法,一种点语法,一种get方法
// 旋转用这个方法CGAffineTransformMakeRotation(M_PI_4);如果在括号里面只是写一个(M_PI_4)的话,旋转也只有一次,不能累减(累加)
//_button.transform = CGAffineTransformMakeRotation(-M_PI_4);// 所以这个只能旋转一次,肯定不是我们最终要得效果。
//利用另外一个函数(方法)CGAffineTransformRotate(CGAffineTransform t, CGFloat angle); 其中CGAffineTransform t是之前的角度,CGFloat angle是要旋转的角度
//_button.transform = CGAffineTransformMakeRotation(-M_PI_4);
if([sender tag] == 5){ //往左
_button.transform = CGAffineTransformRotate(_button.transform, -M_PI_4); // 这样就能够实现连续的左旋转了,但是有个小BUG,就是旋转后,点击向下移,就会从屏幕中消失(待修改)
}else if(6 ==[sender tag]){ // 往右 //常量在前面比较好,这样如果少写一个等号,就会报错
_button.transform = CGAffineTransformRotate(_button.transform, M_PI_4);// 这里是往右旋转,也就是+,但是这个+可写可不写
}
//上面的写法,具有可读性,但是代码量有冗余,可以用三目运算,但是可读性不强
//因为-M_PI_4 = M_PI_4 * -1;
//因为M_PI_4 = M_PI_4 * 1;
//_button.transform = CGAffineTransformRotate(_button.transform, -M_PI_4 * ([sender tag] == 5?1:-1));
}
#pragma mark 伸缩
- (IBAction)telescopic:(id)sender {
//伸缩也是形变属性,所有也是用transform,然后 CGAffineTramMakeScale(CGFloat sx, CGFloat sy);这个方法CGFloat sx是 x的值(控制上下缩放),CGFloat sy是y值(控制左右缩放),默认是1,如果两个值都是1,那么就不变,如果x=0.5,y = 2,这样的意思是,x是之前的一半,y是之前的一倍
//_button.transform = CGAffineTransformMakeScale(0.5, 2); // 这里碰到的结果也是一样,这样的写法也只能缩放一次,所以需要用另外一个函数(方法)CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy); 其中CGAffineTransform t 是当前的值,CGFloat sx, CGFloat sy是传进来的需要缩放的常量
/* 这里用if语句有问题,所以应该用三目运算符
if(7 ==[sender tag]){
_button.transform = CGAffineTransformScale(_button.transform, 1.2, 0.8);
}else if(8 ==[sender tag]){
_button.transform = CGAffineTransformScale(_button.transform, 0.8, 1.2);
}
*/
//1.首先要把 x y值剥离出来,设置成变量 然后用三目运算符,如果tag = 7 那么就放大0.2倍,所以不等于7,就缩小
CGFloat scale = [sender tag] == 7 ? 1.2 : 0.9;
_button.transform = CGAffineTransformScale(_button.transform, scale, scale);
}
@end