UIView 框架、边界和中心 [英] UIView frame, bounds and center

查看:27
本文介绍了UIView 框架、边界和中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何以正确的方式使用这些属性.

据我所知,可以从我正在创建的视图的容器中使用 frame.它设置相对于容器视图的视图位置.它还设置该视图的大小.

也可以从我正在创建的视图的容器中使用 center.此属性更改视图相对于其容器的位置.

最后,bounds 是相对于视图本身的.它改变了视图的可绘制区域.

你能提供更多关于 framebounds 之间关系的信息吗?clipsToBoundsmasksToBounds 属性怎么样?

解决方案

由于我问的问题已经看过很多次了,我会提供一个详细的答案.如果您想添加更多正确的内容,请随时对其进行修改.

首先回顾一下这个问题:框架、边界和中心以及它们之间的关系.

Frame 一个视图的frame(CGRect)是它的矩形在superview的坐标中的位置系统.默认情况下,它从左上角开始.

Bounds 视图的bounds (CGRect) 在它自己的坐标系中表示一个视图矩形.

Center center 是用 superview 的坐标系表示的 CGPoint,它决定了视图的确切中心点的位置.

取自

  • UIView 框架和边界
  • 关于 clipsToBounds(来源 Apple 文档)

    <块引用>

    将此值设置为 YES 会导致子视图被裁剪到边界接收器的.如果设置为 NO,则其框架超出接收器的可见边界不会被剪裁.默认值为否.

    换句话说,如果一个视图的 frame(0, 0, 100, 100) 并且它的子视图是 (90, 90, 30, 30),您将只看到该子视图的一部分.后者不会超出父视图的边界.

    masksToBounds 等价于 clipsToBounds.代替 UIView,此属性应用于 CALayer.在幕后,clipsToBounds 调用 masksToBounds.如需进一步参考,请查看 两者之间的关系如何UIView 的 clipsToBounds 和 CALayer 的 maskToBounds?.

    I would like to know how to use these properties in the right manner.

    As I understand, frame can be used from the container of the view I am creating. It sets the view position relative to the container view. It also sets the size of that view.

    Also center can be used from the container of the view I'm creating. This property changes the position of the view relative to its container.

    Finally, bounds is relative to the view itself. It changes the drawable area for the view.

    Can you give more info about the relationship between frame and bounds? What about the clipsToBounds and masksToBounds properties?

    解决方案

    Since the question I asked has been seen many times I will provide a detailed answer of it. Feel free to modify it if you want to add more correct content.

    First a recap on the question: frame, bounds and center and theirs relationships.

    Frame A view's frame (CGRect) is the position of its rectangle in the superview's coordinate system. By default it starts at the top left.

    Bounds A view's bounds (CGRect) expresses a view rectangle in its own coordinate system.

    Center A center is a CGPoint expressed in terms of the superview's coordinate system and it determines the position of the exact center point of the view.

    Taken from UIView + position these are the relationships (they don't work in code since they are informal equations) among the previous properties:

    • frame.origin = center - (bounds.size / 2.0)

    • center = frame.origin + (bounds.size / 2.0)

    • frame.size = bounds.size

    NOTE: These relationships do not apply if views are rotated. For further info, I will suggest you take a look at the following image taken from The Kitchen Drawer based on Stanford CS193p course. Credits goes to @Rhubarb.

    Using the frame allows you to reposition and/or resize a view within its superview. Usually can be used from a superview, for example, when you create a specific subview. For example:

    // view1 will be positioned at x = 30, y = 20 starting the top left corner of [self view]
    // [self view] could be the view managed by a UIViewController
    UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];    
    view1.backgroundColor = [UIColor redColor];
    
    [[self view] addSubview:view1];
    

    When you need the coordinates to drawing inside a view you usually refer to bounds. A typical example could be to draw within a view a subview as an inset of the first. Drawing the subview requires to know the bounds of the superview. For example:

    UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 400.0f, 400.0f)];    
    view1.backgroundColor = [UIColor redColor];
    
    UIView* view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)];    
    view2.backgroundColor = [UIColor yellowColor];
    
    [view1 addSubview:view2];
    

    Different behaviours happen when you change the bounds of a view. For example, if you change the bounds size, the frame changes (and vice versa). The change happens around the center of the view. Use the code below and see what happens:

    NSLog(@"Old Frame %@", NSStringFromCGRect(view2.frame));
    NSLog(@"Old Center %@", NSStringFromCGPoint(view2.center));    
    
    CGRect frame = view2.bounds;
    frame.size.height += 20.0f;
    frame.size.width += 20.0f;
    view2.bounds = frame;
    
    NSLog(@"New Frame %@", NSStringFromCGRect(view2.frame));
    NSLog(@"New Center %@", NSStringFromCGPoint(view2.center));
    

    Furthermore, if you change bounds origin you change the origin of its internal coordinate system. By default the origin is at (0.0, 0.0) (top left corner). For example, if you change the origin for view1 you can see (comment the previous code if you want) that now the top left corner for view2 touches the view1 one. The motivation is quite simple. You say to view1 that its top left corner now is at the position (20.0, 20.0) but since view2's frame origin starts from (20.0, 20.0), they will coincide.

    CGRect frame = view1.bounds;
    frame.origin.x += 20.0f;
    frame.origin.y += 20.0f;
    view1.bounds = frame; 
    

    The origin represents the view's position within its superview but describes the position of the bounds center.

    Finally, bounds and origin are not related concepts. Both allow to derive the frame of a view (See previous equations).

    View1's case study

    Here is what happens when using the following snippet.

    UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
    view1.backgroundColor = [UIColor redColor];
    
    [[self view] addSubview:view1];
    
    NSLog(@"view1's frame is: %@", NSStringFromCGRect([view1 frame]));
    NSLog(@"view1's bounds is: %@", NSStringFromCGRect([view1 bounds]));
    NSLog(@"view1's center is: %@", NSStringFromCGPoint([view1 center]));
    

    The relative image.

    This instead what happens if I change [self view] bounds like the following.

    // previous code here...
    CGRect rect = [[self view] bounds];
    rect.origin.x += 30.0f;
    rect.origin.y += 20.0f;
    [[self view] setBounds:rect];
    

    The relative image.

    Here you say to [self view] that its top left corner now is at the position (30.0, 20.0) but since view1's frame origin starts from (30.0, 20.0), they will coincide.

    Additional references (to update with other references if you want)

    About clipsToBounds (source Apple doc)

    Setting this value to YES causes subviews to be clipped to the bounds of the receiver. If set to NO, subviews whose frames extend beyond the visible bounds of the receiver are not clipped. The default value is NO.

    In other words, if a view's frame is (0, 0, 100, 100) and its subview is (90, 90, 30, 30), you will see only a part of that subview. The latter won't exceed the bounds of the parent view.

    masksToBounds is equivalent to clipsToBounds. Instead to a UIView, this property is applied to a CALayer. Under the hood, clipsToBounds calls masksToBounds. For further references take a look to How is the relation between UIView's clipsToBounds and CALayer's masksToBounds?.

    这篇关于UIView 框架、边界和中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆