在Storyboard中获取子视图的帧

时间:2012-11-15 21:31:12

标签: ios xcode uistoryboard

我只想(现在)在视图控制器的实例化中获取子视图的尺寸。

[这是一个简单的案例,我可以找到a previous question。我试图弄清楚为什么故事板中的场景子视图不像我期望的那样表现,也就是说:像XIB一样 - 我只想在实际绘制到屏幕之前获取子视图的尺寸]

要将问题压缩到一个新的干净项目,我这样做:

  • 使用“使用Storyboard”选中
  • 创建一个新的单一视图项目
  • 将单个UIView添加到默认的现有MainStoryboard_iPad.storyboard(并将其背景更改为绿色以使其更容易看到 - 除了缩小尺寸之外,这是我从默认的UIView进行的唯一更改我拖到现场)
  • 选项 - 单击导航器中的ViewController.h文件,将其显示在Storyboard框架下方的自己的框架中,并在@interface指令下面插入一对括号
  • 按住Ctrl键并从故事板中的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需要的方法。

2 个答案:

答案 0 :(得分:8)

在调用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);
}

答案 1 :(得分:8)

我有一个相关的问题需要解决,希望能在一天内调试其他人:

我在故事板中发现了这一点:

  1. segue-push 导致subView布局在-viewDidLayoutSubviews它们被替换为布局在-viewDidAppear 之前的其他时间 然而 ......
  2. segue-modal [navController.storyboard presentViewController:] 导致subViews布局-viewDidLayoutSubviews
  3. 解决方案是将[self.mySubView layoutSubviews]置于viewController的{​​{1}}方法中,以便在-viewDidLayoutSubviews内手动加载subView

    我的情况是我有一个自定义渐变按钮,没有正确初始化它的视觉外观 该按钮包含在mySubView中,其中包含scrollView,其中包含自定义渐变按钮 所以,基本上...... CustomView内的视图中的按钮。

    应用程序以scrollView加载其他UINavigationController开始 ViewController1包含一个按钮,当按下该按钮时,会将故事板 ViewController1 发送到segue-push
    这是通过控制 - 从ViewController2中的按钮拖动到ViewController1 来安排在故事板中。

    ViewController2包含ViewController2 / scrollview / customViewcustomButton的{​​{1}}中,我初始化了ViewController2这是一个自定义渐变按钮,它有自己的 .h / .m 文件。
    -viewDidLayoutSubviewscustomButton方法,可以图形方式对其进行配置,并且需要初始化按钮的GradientButton.m / initLayers属性。
    然而 ...
    bounds的{​​{1}}中,frame的框架为0,0,0,0。

    一些注释:

    1. 是的,我在ViewController2开头致电-viewDidLayoutSubviews
    2. self.customButton列出的唯一视图是[super viewDidLayoutSubviews]-viewDidLayoutSubviews的初始视图,在Storyboard的连接面板中已连接。在我的情况下 - {{ 1}}是-viewDidLayoutSubviews )。
    3. 解决:

      1. self.view中,我为包含ViewController2的视图创建了一个插座self.view
      2. scrollView的{​​{1}}中,我致电ViewController2
        • 这将导致self.bottomView的帧/边界被正确设置。
      3. 接下来,我调用self.customButton,现在正确初始化我的自定义渐变按钮。
      4. 关于ViewController2 -viewDidLayoutSubviews调用[self.bottomView layoutSubviews]的一些注释导致customButton的框架被初始化,但不是[self.customButton initLayers]的框架。<登记/> 就视图层次结构而言,ViewController2仅适用于-viewDidLayoutSubviews:的{​​{1}},而不适用于[self.view layoutSubviews]的任何bottomView
        这只是故事板 customButton 的情况。

        故事板 -layoutSubviews 和程序化subView似乎都正确初始化了视图层次结构的所有级别(self.view的{​​{1}}在调用subView时调用。“