1、移动

2、动画

3、缩放

3、旋转

4、简化代码

5、总结

UIButton 的两种状态

normal

highlighted

 1、移动

OC语法规定:不允许直接修改某个对象中结构体属性的成员。

     // 获取image控件的frame
CGRect rect = self.btnImage.frame;
//self.btnImage.frame.origin.y = 20; // 不能直接修改
// 更改Y的值,减小,如果减小到5则一直位5
rect.origin.y -= ;
if( >= rect.origin.y)
{
rect.origin.y = ;
}
// 重新赋值
self.btnImage.frame = rect;

2、动画

这样看起来按钮移动的比较生硬,所以这里给他的移动添加上动画。用到UIView的动画属性

  // 0、动画 (头部-开始动画)
[UIView beginAnimations:nil context:nil];
// 1、获取image控件的frame
CGRect rect = self.btnImage.frame;
//self.btnImage.frame.origin.y = 20; // 不能直接修改
// 2、更改Y的值,减小,如果减小到5则一直位5
rect.origin.y -= ;
if( >= rect.origin.y)
{
rect.origin.y = ;
}
// 3、重新赋值
self.btnImage.frame = rect;
// 4、动画(尾部-提交动画-执行动画)
[UIView commitAnimations];

在设置过动画开始后再加上动画执行时间

    // 设置动画的执行时间
[UIView setAnimationDuration:0.6];

可以看到按钮在平缓移动。

下面是关于动画的一些类方法

 @interface UIView(UIViewAnimation)

 + (void)beginAnimations:(NSString *)animationID context:(void *)context;  // additional context info passed to will start/did stop selectors. begin/commit can be nested
+ (void)commitAnimations; // starts up any animations when the top level animation is commited // no getters. if called outside animation block, these setters have no effect.
+ (void)setAnimationDelegate:(id)delegate; // default = nil
+ (void)setAnimationWillStartSelector:(SEL)selector; // default = NULL. -animationWillStart:(NSString *)animationID context:(void *)context
+ (void)setAnimationDidStopSelector:(SEL)selector; // default = NULL. -animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
+ (void)setAnimationDuration:(NSTimeInterval)duration; // default = 0.2
+ (void)setAnimationDelay:(NSTimeInterval)delay; // default = 0.0
+ (void)setAnimationStartDate:(NSDate *)startDate; // default = now ([NSDate date])
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve; // default = UIViewAnimationCurveEaseInOut
+ (void)setAnimationRepeatCount:(float)repeatCount; // default = 0.0. May be fractional
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses; // default = NO. used if repeat count is non-zero
+ (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState; // default = NO. If YES, the current view position is always used for new animations -- allowing animations to "pile up" on each other. Otherwise, the last end state is used for the animation (the default). + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache; // current limitation - only one per begin/commit block + (void)setAnimationsEnabled:(BOOL)enabled; // ignore any attribute changes while set.
+ (BOOL)areAnimationsEnabled;
+ (void)performWithoutAnimation:(void (^)(void))actionsWithoutAnimation NS_AVAILABLE_IOS(7_0); @end
下面说一些常用的吧:
beginAnimations 开始动画
commitAnimations 执行动画
setAnimationDelegate 设置动画委托
setAnimationDuration 设置动画时间
setAnimationDelay 设置动画延迟时间
setAnimationStartDate 设置动画开始日期
setAnimationCurve  设置动画曲线
setAnimationRepeatCount 设置动画重复次数
setAnimationsEnabled 关闭动画
areAnimationsEnabled 动画是否开启
3、旋转

下面来看按钮的旋转方法 transform属性
旋转方式有两种:
  一种改变弧度 π
  一种改变角度 90
 - (IBAction)RotateLeft
{
// 0、动画头部
[UIView beginAnimations:nil context:nil];
// 设置动画时间
[UIView setAnimationDuration:0.5];
// 1、获取当前的按钮的transform
//_btnImage.transform = CGAffineTransformMakeRotation(-M_PI_4); // 每次都是-45度,所以再次点击没有旋转 _btnImage.transform = CGAffineTransformRotate(_btnImage.transform, -M_PI_4); // 返回新的transform对象,可以连续旋转角度
// 7、动画(尾部-提交动画-执行动画)
[UIView commitAnimations];
}
4、缩放

可以改变frame属性改变大小

     // 0、动画 (头部-开始动画)
[UIView beginAnimations:nil context:nil];
// 设置动画的执行时间
[UIView setAnimationDuration:0.6];
// 1、获取image控件的frame
CGRect rect = self.btnImage.frame;
// 2、获取btn控件的中心
CGPoint point = self.btnImage.center;
//self.btnImage.frame.origin.y = 20; // 不能直接修改
// 3、更改高度和宽度
rect.size.width *= 1.1;
rect.size.height *= 1.1;
// 4、计算新的原点,,保证放大后按钮的中心位置不变
point.x -= rect.size.width/;
point.y -= rect.size.height/;
// 5、将新的原点赋值,
rect.origin = point; // 6、重新赋值
self.btnImage.frame = rect;
//self.btnImage.center = point;
// 7、动画(尾部-提交动画-执行动画)
[UIView commitAnimations];


也可以改变transform属性改变大小,可以想像CGAffineTransformScale内部实现就是方法1
     // 方法2 直接修改transform属性
// 0、动画 (头部-开始动画)
[UIView beginAnimations:nil context:nil];
// 设置动画的执行时间
[UIView setAnimationDuration:0.6];
//_btnImage.transform = CGAffineTransformMakeScale(1.2, 1.2); // 只会改变一次
_btnImage.transform = CGAffineTransformScale(_btnImage.transform, 1.1, 1.1); // 返回修改的transform属性,可连续修改
// 动画(尾部-提交动画-执行动画)
[UIView commitAnimations];
5、简化代码
将上面代码整理后是这样
 // id 类型的不能用点语法
- (IBAction)Run:(id)sender
{
// 0、动画 (头部-开始动画)
[UIView beginAnimations:nil context:nil];
// 设置动画的执行时间
[UIView setAnimationDuration:0.6];
// 1、获取image控件的frame
CGRect rect = self.btnImage.frame;
//self.btnImage.frame.origin.y = 20; // 不能直接修改
switch ([sender tag] )
{
case :
// 2、更改Y的值
rect.origin.y -= DELTA;
break;
case :
// 2、更改Y的值
rect.origin.y += DELTA; break;
case :
// 2、更改x的值
rect.origin.x -= DELTA;
break;
case :
// 2、更改x的值
rect.origin.x += DELTA;
break;
default:
break;
}
// 3、重新赋值
self.btnImage.frame = rect;
// 4、动画(尾部-提交动画-执行动画)
[UIView commitAnimations];
} - (IBAction)Scale:(id)sender
{
// 方法2 直接修改transform属性
// 0、动画 (头部-开始动画)
[UIView beginAnimations:nil context:nil];
// 设置动画的执行时间
[UIView setAnimationDuration:0.6];
//_btnImage.transform = CGAffineTransformMakeScale(1.2, 1.2); // 只会改变一次
float scale = ([sender tag] == ) ? 1.1 : 0.9;
_btnImage.transform = CGAffineTransformScale(_btnImage.transform, scale, scale); // 返回修改的transform属性,可连续修改
// 动画(尾部-提交动画-执行动画)
[UIView commitAnimations]; } - (IBAction)Rotate:(id)sender
{
// 0、动画头部
[UIView beginAnimations:nil context:nil];
// 设置动画时间
[UIView setAnimationDuration:0.5];
// 1、获取当前的按钮的transform
//_btnImage.transform = CGAffineTransformMakeRotation(-M_PI_4); // 每次都是-45度,所以再次点击没有旋转
float rotate = ([sender tag] == ) ? -M_PI_4 : M_PI_4;
_btnImage.transform = CGAffineTransformRotate(_btnImage.transform, rotate);
// 7、动画(尾部-提交动画-执行动画)
[UIView commitAnimations];
}

仔细观察代码可以发现这三个函数的头部好尾部好多重复代码,
如果代码中又很多函数的头部和尾部都有很多重复代码,可以使用block简化代码 先看一下怎么写得
 - (void)btnClickWithBlock:(void(^)())myBlock
{
// 动画 (头部-开始动画)
[UIView beginAnimations:nil context:nil];
// 设置动画的执行时间
[UIView setAnimationDuration:0.6]; myBlock(); // 动画(尾部-提交动画-执行动画)
[UIView commitAnimations];
}
这样写后,后面直接调用这个方法就可以了
 - (void)btnClickWithBlock:(void(^)())myBlock
{
// 动画 (头部-开始动画)
[UIView beginAnimations:nil context:nil];
// 设置动画的执行时间
[UIView setAnimationDuration:0.6]; myBlock(); // 动画(尾部-提交动画-执行动画)
[UIView commitAnimations];
} // id 类型的不能用点语法
- (IBAction)Run:(id)sender
{ [self btnClickWithBlock:^{
// 1、获取image控件的frame
CGRect rect = self.btnImage.frame;
//self.btnImage.frame.origin.y = 20; // 不能直接修改
switch ([sender tag] )
{
case :
// 2、更改Y的值
rect.origin.y -= DELTA;
break;
case :
// 2、更改Y的值
rect.origin.y += DELTA; break;
case :
// 2、更改x的值
rect.origin.x -= DELTA;
break;
case :
// 2、更改x的值
rect.origin.x += DELTA;
break;
default:
break;
}
// 3、重新赋值
self.btnImage.frame = rect; }]; } - (IBAction)Scale:(id)sender
{
[self btnClickWithBlock:^{
//_btnImage.transform = CGAffineTransformMakeScale(1.2, 1.2); // 只会改变一次
float scale = ([sender tag] == ) ? 1.1 : 0.9;
_btnImage.transform = CGAffineTransformScale(_btnImage.transform, scale, scale); // 返回修改的transform属性,可连续修改 }];
} - (IBAction)Rotate:(id)sender
{
[self btnClickWithBlock:^{ // 1、获取当前的按钮的transform
//_btnImage.transform = CGAffineTransformMakeRotation(-M_PI_4); // 每次都是-45度,所以再次点击没有旋转
float rotate = ([sender tag] == ) ? -M_PI_4 : M_PI_4;
_btnImage.transform = CGAffineTransformRotate(_btnImage.transform, rotate); }];
}

这样看来代码简洁了很多。 6、恢复形变属性为原状
CGAffineTransformIdentity 这个Const常量就可以直接恢复原状
 - (IBAction)reset:(id)sender
{
// 恢复所有的形变属性,transform的改变全部恢复
[self btnClickWithBlock:^{
_btnImage.transform = CGAffineTransformIdentity;
}];
}
总结
以上这些属性全部继承自UIView,所以对其他控件也适用。
1、frame 表示控件的位置和尺寸,以父控件左上角位坐标原点
2、center 表示控件的中心,
,以父控件左上角位坐标原点
3、bounds 表示控件的位置和尺寸,以自己左上角位坐标原点,永远是(0,0)
4、transform 表示控件形状属性,缩放,旋转等
5、tag 表示控件的标识,默认是0
 


 

2015-04-25 今日如此,明日依旧。

IOS开发学习笔记018- 一般控件的使用的更多相关文章

  1. Android开发学习笔记-自定义组合控件的过程

    自定义组合控件的过程 1.自定义一个View 一般来说,继承相对布局,或者线性布局 ViewGroup:2.实现父类的构造方法.一般来说,需要在构造方法里初始化自定义的布局文件:3.根据一些需要或者需 ...

  2. Android开发学习笔记-自定义组合控件

    为了能让代码能够更多的复用,故使用组合控件.下面是我正在写的项目中用到的方法. 1.先写要组合的一些需要的控件,将其封装到一个布局xml布局文件中. <?xml version="1. ...

  3. iOS开发UI篇—手写控件,frame,center和bounds属性

    iOS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4 ...

  4. iOS开发UI基础—手写控件,frame,center和bounds属性

    iOS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4 ...

  5. iOS开发基础篇-手写控件

    一.手写控件的步骤 1)使用相应的控件类创建控件对象: 2)设置该控件的各种属性: 3)添加空间到视图中: 4)如果是 UIButton 等控件,还需考虑控件的单击事件等: 二.添加 UIButton ...

  6. WPF-学习笔记 动态修改控件Margin的值

    原文:WPF-学习笔记 动态修改控件Margin的值 举例说明:动态添加一个TextBox到Grid中,并设置它的Margin: TextBox text = new TextBox(); t_gri ...

  7. IOS开发学习笔记019-动态创建控件

    动态创建控件 一.按钮 二.文本输入框 三.lable标签 注意: 只是简单的拖拽控件会毁了你,所以最好还是手动通过代码创建控件. 如果要通过代码生成按钮的话,可以在系统自带的函数viewDidLoa ...

  8. iOS开发学习笔记:基础篇

    iOS开发需要一台Mac电脑.Xcode以及iOS SDK.因为苹果设备都具有自己封闭的环境,所以iOS程序的开发必须在Mac设备上完成(当然,黑苹果应该也是可以的,但就需要花很多的精力去折腾基础环境 ...

  9. iOS开发学习笔记

    1 常用的第三方工具 1.1 iPhone Simulator 测试程序需要模拟器iPhone Simulator 1.2 设计界面需要Interface Builder,Interface Buil ...

随机推荐

  1. C#Udp组播

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  2. springMvc-reset风格和对静态资源的管理

    1.所谓rest风格及比较优雅的,没有一大堆后缀的风格 2.对静态资源的管理,及样式.图片等不需要springMvc过滤 代码: 1.在springMvc的配置文件中添加mvc标签 <?xml ...

  3. LeetCode Single Number III (xor)

    题意: 给一个数组,其中仅有两个元素是出现1次的,且其他元素均出现2次.求这两个特殊的元素? 思路: 跟查找单个特殊的那道题是差不多的,只是这次出现了两个特殊的.将数组扫一遍求全部元素的异或和 x,结 ...

  4. C#,什么是Attribute?什么特性?怎么被调用?

    定制特性attribute,本质上是一个类,其为目标元素提供关联附加信息,并在运行期以反射的方式来获取附加信息(获取到特性类),相当于优雅的为元素添加了一个tag,这个tag是一个类. Attribu ...

  5. IOS Block动画

    ● + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)dur ...

  6. WCF的问题

    使用service调用WCF的时候,有时候会出现 其他信息: HTTP 无法注册 URL 进程不具有此命名空间的访问权限 这样的问题,这时候就需要进行如下尝试: 1,VS的管理权限使用管理员的权限. ...

  7. POJ-1274 The Perfect Stall---二分图模板

    题目链接: https://vjudge.net/problem/POJ-1274 题目大意: 有n个奶牛和m个谷仓,现在每个奶牛有自己喜欢去的谷仓,并且它们只会去自己喜欢的谷仓吃东西,问最多有多少奶 ...

  8. Android(java)学习笔记93:为什么局部内部类只能访问外部类中的 final型的常量

    为什么匿名内部类参数必须为final类型: 1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变 ...

  9. Android(java)学习笔记91:Eclipse中代码提示去掉@override,不然就报错!

    1. Eclipse中提示去掉@Override 把项目下载下来后有@Override的注释的方法会报错,如果把@Override去掉就不报错了.经过查阅后发现:@override注释在jdk1.5环 ...

  10. Spark运行命令示例

    local单机模式:结果xshell可见:./bin/spark-submit --class org.apache.spark.examples.SparkPi --master local[1] ...