4

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

[这是我能找到的上一个问题的简单案例。我试图弄清楚为什么 Storyboards 中场景的子视图的行为不符合我的预期,也就是说:就像 XIB 一样 - 我只想在实际绘制到屏幕上之前获取子视图的尺寸]

为了将问题浓缩为一个新的、干净的项目,我这样做:

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

4

2 回答 2

8

有一个我不得不解决的相关问题,希望可以为其他人节省一天的调试时间:

我在情节提要中发现:

  1. segue-push不会导致ssubView布置在-viewDidLayoutSubviews它们被布置在之前的某个其他时间-viewDidAppear)。
    ...
  2. segue-modal[navController.storyboard presentViewController:] 确实导致subViews-viewDidLayoutSubviews.

解决方案是放在[self.mySubView layoutSubviews]' viewControllers-viewDidLayoutSubviews方法内,以便手动加载subViews 内mySubView

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

该应用程序以加载UINavigationController其他一些内容开始。包含一个按钮,当按下该按钮时,将启动情节提要到. (这是通过控制从按钮拖动到故事板中安排的ViewController1
ViewController1segue-pushViewController2
ViewController1ViewController2

ViewController2包含scrollview// 。customView_ 在's中,我初始化了一个自定义渐变按钮,它拥有自己的.h/.m文件。有一个以图形方式配置它并需要初始化按钮的/属性的方法。但是... in 's的帧为 0,0,0,0。customButton
ViewController2-viewDidLayoutSubviewscustomButton
GradientButton.minitLayersboundsframe

ViewController2-viewDidLayoutSubviewsself.customButton

几点注意事项:

  1. 是的,我[super viewDidLayoutSubviews]在开头打电话-viewDidLayoutSubviews
  2. 唯一布置在的视图-viewDidLayoutSubviewsself.view(ViewController2的初始视图,在 Storyboard 的连接面板中连接。在我的情况下 -self.view是 ascrollView )。

解决:

  1. 在中ViewController2,我self.bottomView为包含self.customButton.
  2. ViewController2's -viewDidLayoutSubviews,我打电话给[self.bottomView layoutSubviews]
    • 这将导致customButton' 框架/边界被正确设置。
  3. 接下来,我调用[self.customButton initLayers]which 现在可以正确初始化我的自定义渐变按钮。

关于ViewController2'-viewDidLayoutSubviews:调用的一些注意事项[self.view layoutSubviews]会导致bottomView' 的框架被初始化,但不是customButton' 的框架。
就视图层次结构而言,-layoutSubviews仅适用于这些subViews 中的 s,self.view而不适用于这些 s 中的任何subViews subView
这似乎只是 storyboard 的情况segue-push

故事板segue-modal和程序[navController presentViewController]似乎都在调用时正确初始化了视图层次结构的所有级别(所有“ subViews of subViews”)-viewDidLayoutSubviews

于 2012-11-29T15:03:08.007 回答
8

这些维度是在调用时计算和设置的layoutSubviews,这发生在viewWillAppear. 在layoutSubviewsUIVIew 上调用后,您可以获得尺寸。

看看在你的视图控制器中实现这个方法: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);
}
于 2012-11-15T22:24:43.983 回答