在Storyboard中获取子视图的框架
我只想(现在)来获取视图控制器实例化上的子视图的维度。
[这是一个简单的例子,我可以find以前的问题 。 我试图弄清楚为什么Storyboard中的场景的子视图并不像我期望的那样运行,也就是说:像XIB一样 – 我只是想在我们的子视图的尺寸实际绘制到屏幕之前得到它的尺寸]
为了把问题简化成一个新的,干净的项目,我这样做:
- 创build一个新的单视图项目“使用故事板”选中
- 将一个UIView添加到默认的
MainStoryboard_iPad.storyboard
(并将其背景更改为绿色以使其更容易看到 – 除了缩小尺寸之外,这是我从默认UIView拖到场景中所做的唯一更改) - 在浏览器中单击
ViewController.h
文件,将其置于Storyboard框架下面的自己的框架中,并在@interface
指令下面插入一对大括号 - 控制单击并拖动从故事板中的UIView到
ViewController.h
并告诉它命名出口firstViewFirstSubView
所以我们现在有ViewController.h
:
#import <UIKit/UIKit.h> @interface ViewController : UIViewController { IBOutlet UIView *firstViewFirstSubView; } @end
然后,我将这个方法添加到ViewController.m:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSLog(@"View Controller will appear. firstViewFirstSubView: %@ ", firstViewFirstSubView); NSLog(@"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width, firstViewFirstSubView.frame.size.height, firstViewFirstSubView.frame.origin.x, firstViewFirstSubView.frame.origin.y); }
在这一点上,我期望能够得到UIView子视图的维度。 但是我得到所有的0,
2012-11-15 15:21:00.743 StoryboardViewBounds[11132:c07] View Controller will appear. firstViewFirstSubView: <UIView: 0x9379730; frame = (0 0; 0 0); autoresize = TM+BM; layer = <CALayer: 0x9378e40>> 2012-11-15 15:21:00.744 StoryboardViewBounds[11132:c07] subView's dimmensions: 0.000000 by 0.000000 at 0.000000, 0.000000
我究竟做错了什么? 看来这应该是非常简单的,所以我认为我必须丢失一些简单的东西,无论是在Storyboard编辑器中投入正确的开关,还是实现Storyboard所需的方法。
当调用layoutSubviews
时,这些维度将被计算并设置,这会在viewWillAppear
之后发生。 在UIVIew上调用layoutSubviews
之后,您可以获得维度。
看看在你的视图控制器中实现这个方法: viewDidLayoutSubviews
。 在这一点上,你应该能够得到你的子视图的尺寸。 请注意,此调用在iOS 5.0中可用,但是由于您参考故事板,因此我认为您正在或高于此值。
- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; NSLog(@"View Controller did layout subviews. firstViewFirstSubView: %@ ", firstViewFirstSubView); NSLog(@"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width, firstViewFirstSubView.frame.size.height, firstViewFirstSubView.frame.origin.x, firstViewFirstSubView.frame.origin.y); }
有一个相关的问题,我不得不解决,这将有助于拯救别人一整天的debugging:
我发现在Storyboard中:
-
segue-push
不会导致子subView
被放置在-viewDidLayoutSubviews
( 它们被放置在另一个时间-viewDidAppear
之前 )。
而 … -
segue-modal
和[navController.storyboard presentViewController:]
的确会导致子subViews
在-viewDidLayoutSubviews
。
解决的办法是把[self.mySubView layoutSubviews]
放在viewController
的-viewDidLayoutSubviews
方法中,以便在subView
手动加载mySubView
。
我的情况是,我有一个自定义渐变button,没有正确初始化它的视觉外观。
该button包含在一个包含自定义渐变button的CustomView
中。
所以,基本上…一个button在一个视图内的一个scrollView
。
该应用程序开始与一个UINavigationController
有一些其他ViewController1
加载。
ViewController1
包含一个button,当按下这个button时,将启动一个storyboard segue-push
到ViewController2
。
( 这是通过控制 – 从ViewController1
的button拖动到ViewController2
) 在故事板中安排的 。
ViewController2
包含scrollview
/ customView
/ customButton
。
在ViewController2
的-viewDidLayoutSubviews
,我初始化了自定义渐变buttoncustomButton
,它具有自己的.h / .m文件。
GradientButton.m
有一个initLayers
方法,它以graphics方式configuration它,并要求初始化button的bounds
/ frame
属性。
不过 …
在ViewController2
的-viewDidLayoutSubviews
, self.customButton
有一个0,0,0,0的框架。
一些注意事项:
- 是的,我在
-viewDidLayoutSubviews
的开头调用[super viewDidLayoutSubviews]
。 - 在
-viewDidLayoutSubviews
布置的唯一视图是-viewDidLayoutSubviews
(ViewController2
的初始视图,在Storyboard的连接面板中连接。 在我的情况下 –scrollView
是一个scrollView
)。
解决:
- 在
ViewController2
,我为包含self.customButton
的视图创build了一个socketsself.customButton
。 - 在
ViewController2
的-viewDidLayoutSubviews
,我调用[self.bottomView layoutSubviews]
- 这将导致
customButton
的框架/边界被正确设置。
- 这将导致
- 接下来,我调用
[self.customButton initLayers]
,现在正确地初始化我的自定义渐变button。
有关ViewController2
的-viewDidLayoutSubviews:
调用[self.view layoutSubviews]
-viewDidLayoutSubviews:
[self.view layoutSubviews]
的一些注意事项会导致bottomView
的框架被初始化,但不是customButton
的框架。
就视图层次而言, -layoutSubviews
仅适用于subView
的子视图, -layoutSubviews
适用于这些subView
视图的-layoutSubviews
视图。
这似乎只是故事板segue-push
。
故事板segue-modal
和编程[navController presentViewController]
都似乎通过[navController presentViewController]
正确初始化视图层次结构的所有级别(所有“ subView
的子subView
”)。