开发 这么长 时间 好多底层的东西 只是简单的接触一下 没有仔细去研究
今天去网上找点资料 ,系统了学习一下UIView
属性 | 说明 |
@property(nonatomic) CGRect frame; | 控件的位置和大小,所有的控件必须指定这个属性,否则即使有控件也无法显示 |
@property(nonatomic) CGRect bounds; | 当前控件位置和大小,但是和frame不同的是它的位置是确定的(0,0) |
@property(nonatomic) CGPoint center; | 控件的中心位置,一般用户进行控件定位 |
@property(nonatomic) CGAffineTransform transform; | 控件矩阵变化,包括平移、缩放、旋转,默认为CGAffineTransformIdentity |
@property(nonatomic) UIViewAutoresizing autoresizingMask; | 控件旋转时大小自动伸缩,默认为UIViewAutoresizingNone |
@property(nonatomic,readonly) UIView *superview; | 当前控件的父控件 |
@property(nonatomic,readonly,copy) NSArray *subviews; | 当前控件的所有一级子控件,注意其子控件的子控件并不包括在内 |
@property(nonatomic,getter=isHidden) BOOL hidden; | 是否隐藏,默认为NO |
@property(nonatomic) UIViewContentMode contentMode; | 内容模式,主要用于指定控件内容(注意不是子控件)如何填充,一般UIImageView经常使用,默认为UIViewContentModeScaleToFill |
@property(nonatomic) NSInteger tag; | 控件的标示,可以存储一些和当前控件有关的信息(但是注意只能是整形),默认为0 |
方法 | 说明 |
- (void)addSubview:(UIView *)view; | 添加子控件 |
- (void)removeFromSuperview; | 从父控件中移除当前控件 |
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index; | 在指定位置插入子控件 |
+ (void)beginAnimations:(NSString *)animationID context:(void *)context; | 开始一段动画 |
+ (void)commitAnimations; | 结束一段动画,注意在开始和结束之间如果控件的某些属性发生变化iOS将以动画方式进行改变 |
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0); | 以block的形式执行一段动画,注意这个方法有几种相关的重载 |
- (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer NS_AVAILABLE_IOS(3_2); | 添加手势操作 |
- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer NS_AVAILABLE_IOS(3_2); | 移除手势操作 |
注意上面所有的位置属性都是相对于其父控件而言(不是相对于屏幕而言),多数属性比较简单这里不再详细解释,我们重点解释一下autoresizingMask、transform属性。
-(NSTimer *)timer
{
if (_timer == nil) {
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(transformAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
}
return _timer;
}
-(void)transformAction{
//给一个float angle 的属性
angle = angle + 0.01;
if (angle > 6.28) {//大于 M_PI*2(360度)角度再次从0开始
angle = 0;
}
self.imageView.transform = CGAffineTransformMakeRotation(angle);
}
一般旋转 都与M_PI有关
、CGAffineTransformMakeScale(缩放)-(void)transformAction{
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, 0.9, 0.9);
}
-(void)transformAction{
self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, 0, 10);
}
- 获得CGAffineTransform有多种方法,例如使用CGAffineTransformMake,但是对于矩阵操作相对比较麻烦,事实上iOS已经为我们准备好了三个方法:CGAffineTransformMakeRotation(旋转)、CGAffineTransformMakeScale(缩放)、CGAffineTransformMakeTranslation(移动);
- transform进行旋转、缩放、移动的时候不是在原来的基础上增量形变的,因此如果需要持续在原来的基础上旋转、缩放、移动那么每次需要在原来的基础上增加或减少。当然,我们可以定义一个全局变量进行累加,但是事实上iOS已经为我们提供好了三个对应的方法,分别用于在原来的角度、缩放、移动位置的基础上做出修改:CGAffineTransformRotate、CGAffineTransformScale、CGAffineTransformTranslate;
- Objc语法规定不允许直接修改一个对象的结构体属性的成员,只能给这个属性直接赋值为一个结构体类型,例如上面的代码中如果写成“_btnRotation.frame.origin.x=380;”是不正确的;
- 上面的代码中我们用到了UIView的动画相关方法,在iOS开发中动画开发异常简单,而且动画和逻辑处理是完全分离的,只要在两个动画方法之间修改一个控件的属性那么当代码执行时就会自动添加动画效果,为了复习前面的block这里我们实现了一个类似于animation方法,类似于UIView的animateWithDuration静态方法的功能,仅仅为了说明它的实现原理,实际开发中可以直接调用animateWithDuration即可(而且它有多种重载);
- animations为动画效果的代码块。
- 下面是可以设置动画效果的属性:
- frame
- bounds
- center 中心
- transform 转变 是移动 缩放 还是旋转
- alpha 透明度
- backgroundColor 背景颜色
- (void)bringSubviewToFront:(UIView *)view;
view.layer.cornerRadius = 10;
view.layer.masksToBounds = YES;//这个方法是设置View layer的 覆盖层的属性 超出范围就切掉
view.clipsToBounds = YES; //这个方法是设置View的属性 切除超过父视图的部分 功能和上面的相同 只是 一个layer一个 是本身就可以用了
4.顺便提下,在实际开发中可能遇到这种需求,当tableView 滑动到某个位置的时候才显示新手引导. 这时候就需要将tableView上的坐标转化为相对于屏幕的坐标. 可用原生的方法:
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;