【问题标题】:Getting subViews' frames in Storyboard在 Storyboard 中获取子视图的帧
【发布时间】:2012-11-15 21:31:11
【问题描述】:

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

[这是我能找到的a previous question 的简单案例。我试图弄清楚为什么 Storyboards 中场景的子视图没有按我预期的方式运行,也就是说:就像 XIB 一样 - 我只想在实际绘制到屏幕之前获取子视图的尺寸]

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

  • 创建一个新的单视图项目并选中“使用 Storyboard”
  • 将单个 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 需要的方法。

【问题讨论】:

    标签: ios xcode uistoryboard


    【解决方案1】:

    这些维度是在调用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);
    }
    

    【讨论】:

    • 这个成功了,谢谢!我想知道为什么布局文件中初始信息的可用性在我们使用 XIB 文件(以及我使用的所有使用 XIB 文件的教程代码,早在viewDidLoad)和他们实现 Storyboard 之间发生了变化。无论如何-谢谢!
    【解决方案2】:

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

    我在 Storyboard 中发现了这一点:

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

    解决方案是将[self.mySubView layoutSubviews] 放在viewController-viewDidLayoutSubviews 方法中,以便在mySubView 中手动加载subViews。

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

    应用程序以 UINavigationController 开始,并加载了其他一些 ViewController1
    ViewController1 包含一个按钮,按下该按钮时,将启动故事板 segue-push 到 @987654341 @.
    这是通过从ViewController1 中的按钮控制拖动到ViewController2 来安排在情节提要中的

    ViewController2 包含scrollview/customView/customButton
    ViewController2-viewDidLayoutSubviews 中,我初始化了customButton,这是一个自定义渐变按钮,有自己的.h/.m 文件。
    GradientButton.m 有一个initLayers以图形方式配置它并需要初始化按钮的 bounds/frame 属性的方法。
    但是...
    ViewController2-viewDidLayoutSubviews 中,self.customButton 的帧为 0,0,0,0。

    几点说明:

    1. 是的,我在-viewDidLayoutSubviews 的开头调用[super viewDidLayoutSubviews]
    2. -viewDidLayoutSubviews 布置的唯一视图是self.viewViewController2 的初始视图,在 Storyboard 的连接面板中连接。在我的情况下 - self.viewscrollView )。

    解决:

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

    关于ViewController2-viewDidLayoutSubviews: 调用[self.view layoutSubviews] 的一些注意事项导致bottomView 的框架被初始化,但不是customButton 的框架。
    在视图层次结构方面,-layoutSubviews 仅适用于 self.view 中的 subViews,而不适用于 subViews 中的任何 subViews。
    只有情节提要 segue-push 才会出现这种情况。

    情节提要 segue-modal 和程序化的[navController presentViewController] 似乎都正确初始化了视图层次结构的所有级别(subViews 的所有“subViews”)到时间@ 987654388@ 被调用。

    【讨论】:

    • 非常感谢,遇到完全相同的情况
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 2023-03-21
    相关资源
    最近更新 更多