视图UIView的frame、bounds与center属性

http://blog.csdn.net/pucker/article/details/7634479

UIView类中定义了三个属性,分别是frame、bounds与center属性:

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. @property

    (

    nonatomic

    ) CGRect frame;

  2. @property

    (

    nonatomic

    ) CGRect bounds;

  3. @property

    (

    nonatomic

    ) CGPoint center;

在详细介绍这三个属性之前,我们应该知道UIKit中的坐标系X轴正方向为水平向右,Y轴正方向为竖直向下。

frame属性指的是视图在其父视图坐标系中的位置与尺寸。在创建视图时,我们就需要在初始化方法中指定视图的frame:

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

    • (

    id

    )initWithFrame:(CGRect)frame;

这样创建了视图之后,通过addSubview:方法就可以将创建的子视图放置在父视图的指定位置,并以指定的尺寸显示出来。

center属性理解起来也很简单,它就是视图的中心点在其父视图坐标系中的位置坐标。简单讲,center属性就定义了当前视图在父视图中的位置。

那么bounds属性呢?它指的是视图在其自己的坐标系中的位置与尺寸。

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

    • (

    BOOL

    )application:(

    UIApplication

    *)application

    didFinishLaunchingWithOptions

    :(

    NSDictionary

    *)launchOptions

  1. {

  2. self

    .window

    = [[UIWindow

    alloc

    ]

    initWithFrame

    :[[UIScreen

    mainScreen

    ]

    bounds

    ]];

  3. // Override point for customization after application launch.

  4. self

    .window

    .backgroundColor

    = [UIColor

    whiteColor

    ];

  5. UIView* testView = [[UIView

    alloc

    ]

    initWithFrame

    :CGRectMake(

    5

    0

    ,

    5

    0

    ,

    1

    0

    0

    ,

    1

    0

    0

    )];

  6. testView

    .backgroundColor

    = [UIColor

    redColor

    ];

  7. [

    self

    .window

    addSubview

    :testView];

  8. NSLog(

@"Frame: (%.2f, %.2f, %.2f, %.2f)"

, testView

.frame

.origin

.x

, testView

.frame

.origin

.y

, testView

.frame

.size

.width

, testView

.frame

.size

.height

);
  1. NSLog(
@"Bounds: (%.2f, %.2f, %.2f, %.2f)"

, testView

.bounds

.origin

.x

, testView

.bounds

.origin

.y

, testView

.bounds

.size

.width

, testView

.bounds

.size

.height

);
  1. NSLog(
@"Center: (%.2f, %.2f)"

, testView

.center

.x

, testView

.center

.y

);
  1. [
self

.window

 makeKeyAndVisible

];
  1. return
YES

;
  1. }

输出:

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. Frame: (

    5

    0

    .00

    ,

    5

    0

    .00

    ,

    1

    0

    0

    .00

    ,

    1

    0

    0

    .00

    )

  2. Bounds: (

    0

    .00

    ,

    0

    .00

    ,

    1

    0

    0

    .00

    ,

    1

    0

    0

    .00

    )

  3. Center: (

    1

    0

    0

    .00

    ,

    1

    0

    0

    .00

    )

运行界面:

image

图1

由于视图的定位一定需要针对父视图,而不是针对自己,所以bounds属性并不能够决定当前视图的位置(因为它与父视图根本无关,就谈不上定位),所以bounds属性与center属性是完全独立的,前者规定尺寸,后者定义位置。换句话说,修改bounds不影响center;修改center不影响bounds。(《iOS应用程序开发方法与实践》中讲到当修改bounds时center会更改,这是一个错误。特附此文。)

默认情况下,当视图创建后,其自己的坐标系原点(0, 0)位于其左上角位置。不过,本地原点位置是会随时发生变化的。例如将bounds由最初的(0, 0, 100, 100)修改为(50, 50, 100, 100),则意味着本地原点向左向上移动了50。由于位置和尺寸都未发生变化,所以frame属性与center属性不变。在[self.window makeKeyAndVisible];语句之前加入下面的代码:

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. NSLog(

    @"Modify Bounds to (50, 50, 100, 100)"

    );

  2. testView

    .bounds

    = CGRectMake(

    5

    0

    ,

    5

    0

    ,

    1

    0

    0

    ,

    1

    0

    0

    );

  3. NSLog(

    @"Frame: (%.2f, %.2f, %.2f, %.2f)"

    , testView

    .frame

    .origin

    .x

    , testView

    .frame

    .origin

    .y

    , testView

    .frame

    .size

    .width

    , testView

    .frame

    .size

    .height

    );

  4. NSLog(

    @"Bounds: (%.2f, %.2f, %.2f, %.2f)"

    , testView

    .bounds

    .origin

    .x

    , testView

    .bounds

    .origin

    .y

    , testView

    .bounds

    .size

    .width

    , testView

    .bounds

    .size

    .height

    );

  5. NSLog(

    @"Center: (%.2f, %.2f)"

    , testView

    .center

    .x

    , testView

    .center

    .y

    );

输出:

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. Modify Bounds to (

    5

    0

    ,

    5

    0

    ,

    1

    0

    0

    ,

    1

    0

    0

    )

  2. Frame: (

    5

    0

    .00

    ,

    5

    0

    .00

    ,

    1

    0

    0

    .00

    ,

    1

    0

    0

    .00

    )

  3. Bounds: (

    5

    0

    .00

    ,

    5

    0

    .00

    ,

    1

    0

    0

    .00

    ,

    1

    0

    0

    .00

    )

  4. Center: (

    1

    0

    0

    .00

    ,

    1

    0

    0

    .00

    )

运行界面依然是图1。

再例如将bounds由最初的(0, 0, 100, 100)修改为(0, 0, 140, 140),则本地原点向左向上移动20。frame属性变为(30, 30, 140, 140),center属性不变,仍然是(100, 100)。

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_7" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. NSLog(

    @"Modify Bounds to (0, 0, 140, 140)"

    );

  2. testView

    .bounds

    = CGRectMake(

    0

    ,

    0

    ,

    1

    4

    0

    ,

    1

    4

    0

    );

  3. NSLog(

    @"Frame: (%.2f, %.2f, %.2f, %.2f)"

    , testView

    .frame

    .origin

    .x

    , testView

    .frame

    .origin

    .y

    , testView

    .frame

    .size

    .width

    , testView

    .frame

    .size

    .height

    );

  4. NSLog(

    @"Bounds: (%.2f, %.2f, %.2f, %.2f)"

    , testView

    .bounds

    .origin

    .x

    , testView

    .bounds

    .origin

    .y

    , testView

    .bounds

    .size

    .width

    , testView

    .bounds

    .size

    .height

    );

  5. NSLog(

    @"Center: (%.2f, %.2f)"

    , testView

    .center

    .x

    , testView

    .center

    .y

    );

输出:

[plain]

view plain

copy

<embed id="ZeroClipboardMovie_8" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_8" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=8&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. Modify Bounds to (0, 0, 140, 140)

  2. Frame: (30.00, 30.00, 140.00, 140.00)

  3. Bounds: (0.00, 0.00, 140.00, 140.00)

  4. Center: (100.00, 100.00)

运行界面:

image

图2

现在我们把testView改回为最初的状态,并在其中添加一个子视图greenView。

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_9" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_9" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=9&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

    • (

    BOOL

    )application:(

    UIApplication

    *)application

    didFinishLaunchingWithOptions

    :(

    NSDictionary

    *)launchOptions

  1. {

  2. self

    .window

    = [[UIWindow

    alloc

    ]

    initWithFrame

    :[[UIScreen

    mainScreen

    ]

    bounds

    ]];

  3. // Override point for customization after application launch.

  4. self

    .window

    .backgroundColor

    = [UIColor

    whiteColor

    ];

  5. UIView* testView = [[UIView

    alloc

    ]

    initWithFrame

    :CGRectMake(

    5

    0

    ,

    5

    0

    ,

    1

    0

    0

    ,

    1

    0

    0

    )];

  6. testView

    .backgroundColor

    = [UIColor

    redColor

    ];

  7. [

    self

    .window

    addSubview

    :testView];

  8. UIView* greenView = [[UIView

    alloc

]

 initWithFrame

:CGRectMake(

3

0

, 

3

0

, 

8

0

, 

8

0

)];
  1. greenView
.backgroundColor

 = [UIColor

 greenColor

];
  1. [testView

    addSubview

:greenView];
  1. NSLog(
@"testView Frame: (%.2f, %.2f, %.2f, %.2f)"

, testView

.frame

.origin

.x

, testView

.frame

.origin

.y

, testView

.frame

.size

.width

, testView

.frame

.size

.height

);
  1. NSLog(
@"testView Bounds: (%.2f, %.2f, %.2f, %.2f)"

, testView

.bounds

.origin

.x

, testView

.bounds

.origin

.y

, testView

.bounds

.size

.width

, testView

.bounds

.size

.height

);
  1. NSLog(
@"testView Center: (%.2f, %.2f)"

, testView

.center

.x

, testView

.center

.y

);
  1. NSLog(
@"greenView Frame: (%.2f, %.2f, %.2f, %.2f)"

, greenView

.frame

.origin

.x

, greenView

.frame

.origin

.y

, greenView

.frame

.size

.width

, greenView

.frame

.size

.height

);
  1. NSLog(
@"greenView Bounds: (%.2f, %.2f, %.2f, %.2f)"

, greenView

.bounds

.origin

.x

, greenView

.bounds

.origin

.y

, greenView

.bounds

.size

.width

, greenView

.bounds

.size

.height

);
  1. NSLog(
@"greenView Center: (%.2f, %.2f)"

, greenView

.center

.x

, greenView

.center

.y

);
  1. [
self

.window

 makeKeyAndVisible

];
  1. return
YES

;
  1. }

输出:

[plain]

view plain

copy

<embed id="ZeroClipboardMovie_10" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_10" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=10&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. testView Frame: (50.00, 50.00, 100.00, 100.00)

  2. testView Bounds: (0.00, 0.00, 100.00, 100.00)

  3. testView Center: (100.00, 100.00)

  4. greenView Frame: (30.00, 30.00, 80.00, 80.00)

  5. greenView Bounds: (0.00, 0.00, 80.00, 80.00)

  6. greenView Center: (70.00, 70.00)

界面:

image

图3

然后在[self.window makeKeyAndVisible];语句之前加入下面的代码,将testView的bounds改为(50, 50, 100, 100):

[objc]

view plain

copy

<embed id="ZeroClipboardMovie_11" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_11" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=11&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. NSLog(

    @"Modify testView Bounds to (50, 50, 100, 100)"

    );

  2. testView

    .bounds

    = CGRectMake(

    5

    0

    ,

    5

    0

    ,

    1

    0

    0

    ,

    1

    0

    0

    );

  3. NSLog(

    @"testView Frame: (%.2f, %.2f, %.2f, %.2f)"

    , testView

    .frame

    .origin

    .x

    , testView

    .frame

    .origin

    .y

    , testView

    .frame

    .size

    .width

    , testView

    .frame

    .size

    .height

    );

  4. NSLog(

    @"testView Bounds: (%.2f, %.2f, %.2f, %.2f)"

    , testView

    .bounds

    .origin

    .x

    , testView

    .bounds

    .origin

    .y

    , testView

    .bounds

    .size

    .width

    , testView

    .bounds

    .size

    .height

    );

  5. NSLog(

    @"testView Center: (%.2f, %.2f)"

    , testView

    .center

    .x

    , testView

    .center

    .y

    );

  6. NSLog(

    @"greenView Frame: (%.2f, %.2f, %.2f, %.2f)"

    , greenView

    .frame

    .origin

    .x

    , greenView

    .frame

    .origin

    .y

    , greenView

    .frame

    .size

    .width

    , greenView

    .frame

    .size

    .height

    );

  7. NSLog(

    @"greenView Bounds: (%.2f, %.2f, %.2f, %.2f)"

    , greenView

    .bounds

    .origin

    .x

    , greenView

    .bounds

    .origin

    .y

    , greenView

    .bounds

    .size

    .width

    , greenView

    .bounds

    .size

    .height

    );

  8. NSLog(

    @"greenView Center: (%.2f, %.2f)"

    , greenView

    .center

    .x

    , greenView

    .center

    .y

    );

输出:

[plain]

view plain

copy

<embed id="ZeroClipboardMovie_12" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="17" height="16" name="ZeroClipboardMovie_12" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=12&width=17&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. testView Frame: (50.00, 50.00, 100.00, 100.00)

  2. testView Bounds: (0.00, 0.00, 100.00, 100.00)

  3. testView Center: (100.00, 100.00)

  4. greenView Frame: (30.00, 30.00, 80.00, 80.00)

  5. greenView Bounds: (0.00, 0.00, 80.00, 80.00)

  6. greenView Center: (70.00, 70.00)

  7. Modify testView Bounds to (50, 50, 100, 100)

  8. testView Frame: (50.00, 50.00, 100.00, 100.00)

  9. testView Bounds: (50.00, 50.00, 100.00, 100.00)

  10. testView Center: (100.00, 100.00)

  11. greenView Frame: (30.00, 30.00, 80.00, 80.00)

  12. greenView Bounds: (0.00, 0.00, 80.00, 80.00)

  13. greenView Center: (70.00, 70.00)

界面:

image

图4

由于testView自己坐标的原点被移动到了屏幕的左上角位置,所以greenView在界面上的位置也相应发生了变化。所以,当修改了视图自身的原点位置时,不会影响其自身的位置,而会影响到其子视图的位置。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容