UIView详解

来源:互联网 发布:ubuntu启动anaconda 编辑:程序博客网 时间:2024/06/05 06:14

一个UIView的实例就是一个视图,表示的是屏幕上的一块矩形区域

作用有:

负责这块矩形区域的描绘以及和用户的交互。

第一、UIView的可视化属性

1. backgroundColor  背景属性

2. hidden  表示该view是否隐藏,

hidden属性为YES时视图隐藏,否则不隐藏。

3. alpha  为0时完全透明,为1时完全不透明

注意事项:

当视图完全透明或者隐藏时,不能响应触摸消息。

也就是alpha等于0.0或者hidden为YES的时候,但是当alpha<0.01的时候,视图就已经接收不到消息了。

 视图的alpha值会影响子视图的绘制,但是子视图的alpha值不变。

4. opaque  property
这是一个优化属性,如果该值为YES, 那么绘图在绘制该视图的时候把整个视图当作不透明对待。这样,绘图系统在执行绘图过程中会优化一些操作并提升系统性能;如果是设置为NO, 绘图系统将其和其他内容平等对待,不去做优化操作。为了性能方面的考量,默认被置为YES(意味着‘优化’)。
另一方面,这个消息和alpha 是有关系的。 一个不透明视图需要整个边界里面的内容都是不透明的。基于这个原因,opaque设置为YES,要求对应的alpha必须为1.0。如果一个UIView实例opaque被设置为YES, 而同时它又没有完全填充它的边界(bounds),或者它包含了整个或部分的透明的内容视图,那么将会导致未知的结果。
因此,如果视图部分或全部支持透明,那么你必须把opaque这个值设置为NO. 

5. clipsToBounds  

在类的层次结构中,如果clipsTobounds设为YES,超出superView的部分subview就不会显示,否则会做显示, 默认情况下是NO。

6. clearsContextBeforeDrawing  

A Boolean value that determines whether the receiver’s bounds should be automatically cleared before drawing.

7. layerClass和 layer  property 跟Core Animation layer有关

第二、管理视图层次

1. superview  property 返回该view的superView

sample:

    [self.windowaddSubview:self.viewController.view];

   NSLog(@"the superView is %@",[self.viewController.viewsuperview]);

2. subviews  property 返回该view的subviews

sample:

    NSLog(@"the suberViews are %@",[self.window subviews]);

3. window  property 返回该view的window,如果没有返回nil

    NSLog(@"the window is %@",[self.viewController.viewwindow]);

4. – addSubview:

5. – bringSubviewToFront:

把指定的子view放到最顶层,其父视图调用bringSubviewToFront()方法。

sample:

[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIButton *button=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 50, 50)] autorelease];
    button.backgroundColor=[UIColor redColor];
    [self.view addSubview:button];
    UIButton *button2=[[[UIButton alloc] initWithFrame:CGRectMake(130, 130, 50, 50)] autorelease];
    button2.backgroundColor=[UIColor blueColor];
    [self.view addSubview:button2];
    [self.view bringSubviewToFront:button];

6.--sendSubviewToBack:

将一个UIView层推送到背后只需要调用其父视图的 sendSubviewToBack()方法。

sample:

     [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIButton *button=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 50, 50)] autorelease];
    button.backgroundColor=[UIColor redColor];
    [self.view addSubview:button];
    UIButton *button2=[[[UIButton alloc] initWithFrame:CGRectMake(130, 130, 50, 50)] autorelease];
    button2.backgroundColor=[UIColor blueColor];
    [self.view addSubview:button2];
    [self.view sendSubviewToBack:button2];

7.– removeFromSuperview

sample:

[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIButton *button=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 50, 50)] autorelease];
    button.backgroundColor=[UIColor redColor];
    [self.view addSubview:button];
    
    UIButton *button2=[[[UIButton alloc] initWithFrame:CGRectMake(130, 130, 50, 50)] autorelease];
    button2.backgroundColor=[UIColor blueColor];
    [self.view addSubview:button2];
    [button removeFromSuperview];

8.– insertSubview:atIndex:

Parameters

view

The view to insert. This value cannot benil.

index

The index in the array of thesubviews property at which to insert the view. Subview indices start at0 and cannot be greater than the number of subviews.

sample:

  [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIButton *button=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 50, 50)] autorelease];
    button.backgroundColor=[UIColor redColor];
    [self.view addSubview:button];
    UIButton *button2=[[[UIButton alloc] initWithFrame:CGRectMake(130, 130, 50, 50)] autorelease];
    button2.backgroundColor=[UIColor blueColor];
    [self.view addSubview:button2];  
    UIButton *button3=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 100, 100)] autorelease];
    button3.backgroundColor=[UIColor greenColor];
    [self.view insertSubview:button3 atIndex:2];

9.– insertSubview:aboveSubview

Inserts a view above another view in the view hierarchy.

- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview

sample:

[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIButton *button=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 50, 50)] autorelease];
    button.backgroundColor=[UIColor redColor];
    [self.view addSubview:button];
    UIButton *button2=[[[UIButton alloc] initWithFrame:CGRectMake(130, 130, 50, 50)] autorelease];
    button2.backgroundColor=[UIColor blueColor];
    [self.view addSubview:button2];
    UIButton *button3=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 100, 100)] autorelease];
    button3.backgroundColor=[UIColor greenColor];
    [self.view insertSubview:button3 aboveSubview:button];

10.– insertSubview:belowSubview:

 [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIButton *button=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 50, 50)] autorelease];
    button.backgroundColor=[UIColor redColor];
    [self.view addSubview:button];
    UIButton *button2=[[[UIButton alloc] initWithFrame:CGRectMake(130, 130, 50, 50)] autorelease];
    button2.backgroundColor=[UIColor blueColor];
    [self.view addSubview:button2]; 
    UIButton *button3=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 100, 100)] autorelease];
    button3.backgroundColor=[UIColor greenColor];
    [self.view insertSubview:button3 belowSubview:button];

11.– exchangeSubviewAtIndex:withSubviewAtIndex:

- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2

Parameters

index1

The index of the first subview in the receiver.

index2

The index of the second subview in the receiver.

sample:

   [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIButton *button=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 50, 50)] autorelease];
    button.backgroundColor=[UIColor redColor];
    [self.view addSubview:button];
    UIButton *button2=[[[UIButton alloc] initWithFrame:CGRectMake(130, 130, 50, 50)] autorelease];
    button2.backgroundColor=[UIColor blueColor];
    [self.view addSubview:button2];
    UIButton *button3=[[[UIButton alloc] initWithFrame:CGRectMake(120, 120, 100, 100)] autorelease];
    button3.backgroundColor=[UIColor greenColor];
    [self.view addSubview:button3];
    [self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:3];

12– isDescendantOfView:

Returns a Boolean value indicating whether the receiver is a subview of a given view or identical to that view.

- (BOOL)isDescendantOfView:(UIView *)view

sample:

    NSLog(@"the result is %d",[button3isDescendantOfView:self.view]);


第四、调整大小的相关属性或函数(Configuring the Resizing Behavior)

1. autoresizingMask  property

 概属性用来指出当父窗口发生变化时,子窗口应该如何变

  如果视图的autoresizesSubviews属性声明被设置为YES,则其子视图会根据autoresizingMask属性的值自动进行尺寸调整。简单配置一下视图的自动尺寸调整掩码常常就能使应用程序得到合适的行为;否则,应用程序就必须通过重载layoutSubviews方法来提供自己的实现。

2. autoresizesSubviews  property
返回值为true或false,表示当父窗口发生变化时,子窗口是否应该变化

3.  contentMode  property

主要用在UIImageView,当窗口大小和图片大小不一样时,通过该字段选择合适的布局方式。

4. – sizeThatFits:

Asks the view to calculate and return the size that best fits its subviews.

- (CGSize)sizeThatFits:(CGSize)size
Parameters
size

The current size of the receiver.

Return Value

A new size that fits the receiver’s subviews.

5. – sizeToFit

Resizes and moves the receiver view so it just encloses its subviews.

- (void)sizeToFit得到最适合当前字数的尺寸,
  UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 70, 20)];
    label.backgroundColor = [UIColor blueColor];
    label.text = @"fdsafasfsaaaaaaaaaaaaaa";
    [self.view addSubview:label];
    NSLog(@"bounds %@",NSStringFromCGRect(label.frame));
    [label sizeToFit];
    NSLog(@"bounds is %@",NSStringFromCGRect(label.frame));
返回结果是:

2013-09-02 18:39:16.284 single[1494:c07] bounds {{0, 0}, {70, 20}}

2013-09-02 18:39:16.285 single[1494:c07] bounds is {{0, 0}, {201, 21}}

第五、Laying out Subviews

1. – layoutSubviews

这个方法是当你需要在调整subview的大小的时候需要重写(我这个翻译不严谨,以下是原文:You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.),但有时候经常指望它被调用的时候没被调用,不希望它被调用的时候被调用了,搞的很上火。根据国外社区一个人帖子,做了总结性翻译。

layoutSubviews在以下情况下会被调用:

1、init初始化不会触发layoutSubviews

2、addSubview会触发layoutSubviews

3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化

4、滚动一个UIScrollView会触发layoutSubviews

5、旋转Screen会触发父UIView上的layoutSubviews事件

6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

2. – setNeedsLayout

3. – layoutIfNeeded

-setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用
-layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)

如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局

在视图第一次显示之前,标记总是“需要刷新”的,可以直接调用[view layoutIfNeeded]

4.UIView的setNeedsDisplay和setNeedsLayout方法。首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画了。而setNeedsLayout会默认调用layoutSubViews,就可以处理子视图中的一些数据。
宗上所诉,setNeedsDisplay方便绘图,而layoutSubViews方便出来数据

第六、Configuring the Event-Related Behavior

1.  userInteractionEnabled  property

A Boolean value that determines whether user events are ignored and removed from the event queue.

@property(nonatomic, getter=isUserInteractionEnabled) BOOL userInteractionEnabled

最简单的比如说让给一个button在点击时,没有响应,可以设置这个值为no

2.  multipleTouchEnabled  property

A Boolean value that indicates whether the receiver handles multi-touch events.

@property(nonatomic, getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled

Discussion

When set to YES, the receiver receives all touches associated with a multi-touch sequence. When set toNO, the receiver receives only the first touch event in a multi-touch sequence. The default value of this property isNO.

Other views in the same window can still receive touch events when this property isNO. If you want this view to handle multi-touch events exclusively, set the values of both this property and theexclusiveTouch property to YES.

3.   exclusiveTouch  property

A Boolean value that indicates whether the receiver handles touch events exclusively.

第七. 利用tag来查找UIView

    [superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

    UIView *view1=[[[UIViewalloc]initWithFrame:CGRectMake(50,50,100,100)]autorelease];

    view1.backgroundColor=[UIColorredColor];

    view1.tag=101;

    [self.view addSubview:view1];

    UIView *view2=[[[UIViewalloc]initWithFrame:CGRectMake(150,150,200,200)]autorelease];

    view2.backgroundColor=[UIColorblueColor];

    view2.tag=102;

    [self.view addSubview:view2];

    UIView *view3=[[[UIViewalloc]initWithFrame:CGRectMake(150,150,200,200)]autorelease];

    view3.backgroundColor=[UIColorblueColor];

    view3.tag=103;

    [view2 addSubview:view3];

    NSLog(@"the view1 is %@",[self.viewviewWithTag:102]);

    NSLog(@"the subviews are %@",[self.viewsubviews]);

    NSLog(@"the superview is %@",[view3superview]);

第十、当调用addsubView的时候,会对其进行保留,理解为retain一个对象就可以,当调用removeFromSuperView,会对释放,也就是release

如果手动创建了视图,分配了任何内存、存储了任何对象的引用,都需要释放资源,必须实现dealloc方法,当某个对象的引用计数为0时,系统会调用dealloc方法,去释放对象的资源,切记不要手动调用dealloc方法

第十一、重绘

-drawRect:(CGRect)rect方法:重写此方法,执行重绘任务
-setNeedsDisplay方法:标记为需要重绘,异步调用drawRect
-setNeedsDisplayInRect:(CGRect)invalidRect方法:标记为需要局部重绘

layoutSubviews对subviews重新布局

layoutSubviews方法调用先于drawRect

setNeedsLayout在receiver标上一个需要被重新布局的标记,在系统runloop的下一个周期自动调用layoutSubviews

layoutIfNeeded方法如其名,UIKit会判断该receiver是否需要layout.根据Apple官方文档,layoutIfNeeded方法应该是这样的

 layoutIfNeeded遍历的不是superview链,应该是subviews链

drawRect是对receiver的重绘,能获得context

setNeedDisplay在receiver标上一个需要被重新绘图的标记,在下一个draw周期自动重绘,iphone device的刷新频率是60hz,也就是1/60秒后重绘

 第十二、视图之间坐标点的转换
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
Converts a point from the receiver’s coordinate system to that of the specified view
- (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view

Converts a rectangle from the coordinate system of another view to that of the receiver.

[aView convertPoint:p toView:anotherView]是指将p相对aView的坐标转换为相对anotherView的坐标

比如说aView是原点(0,0), 宽高(1024, 768)的视图

anotherView是aView的子视图,原点是(100, 0),宽高(200, 200)

那么一个在anotherView中坐标是(0, 0)的点经过转换后在aView的坐标是(100, 0)

第十三、Being Prepared for Layout Changes
Layout changes can occur whenever any of the following events happens in a view:
  1. The size of a view’s bounds rectangle changes.
  2. An interface orientation change occurs, which usually triggers a change in the root view’s bounds rectangle.
  3. The set of Core Animation sublayers associated with the view’s layer changes and requires layout.
  4. Your application forces layout to occur by calling the setNeedsLayout or layoutIfNeeded method of a view.
  5. Your application forces layout by calling the setNeedsLayout method of the view’s underlying layer object.

第十四、autoresizingMask的属性
属性的意思就是自动调整子控件与父控件中间的位置,宽高,默认值是UIViewAutoresizingNone
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
UIViewAutoresizingNone就是不自动调整。
UIViewAutoresizingFlexibleLeftMargin 自动调整与superView左边的距离,保证与superView右边的距离不变。
UIViewAutoresizingFlexibleRightMargin 自动调整与superView的右边距离,保证与superView左边的距离不变。
UIViewAutoresizingFlexibleTopMargin 自动调整与superView顶部的距离,保证与superView底部的距离不变。
UIViewAutoresizingFlexibleBottomMargin 自动调整与superView底部的距离,也就是说,与superView顶部的距离不变。
UIViewAutoresizingFlexibleWidth 自动调整自己的宽度,保证与superView左边和右边的距离不变。
UIViewAutoresizingFlexibleHeight 自动调整自己的高度,保证与superView顶部和底部的距离不变。
UIViewAutoresizingFlexibleLeftMargin  |UIViewAutoresizingFlexibleRightMargin 自动调整与superView左边的距离,保证与左边的距离和右边的距离和原来距左边和右边的距离的比例不变。比如原来距离为20,30,调整后的距离应为68,102,即68/20=102/30。

第十五、创建layer

+ (Class)layerClass
{
    return [CATiledLayer class];
}
view创建之后,它的layer类型不能改变。因此每个视图都是使用layerClass类方法来改变layer对象。这个方法的缺省实现是返回 CALayer,修改这个值的唯一方法是实现一个子类,override这个方法,返回不同的值.





原创粉丝点击