为什么我的一些UIViews在导航后会被移动?

时间:2010-01-27 04:06:05

标签: uiview statusbar pushviewcontroller

在我的一些应用程序设计或仅仅是一些UIViews中,在navigationController的pushViewController之后,我的新视图将从状态栏的高度移出窗口。因此,我将此代码存根放在viewDidLoad方法中。

CGRect  frameAt = [self.view frame];
CGRect  statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
frameAt.origin.y += statusBarFrame.size.height;
[self.view setFrame: frameAt];

这对我来说没有意义,这是XCode和Interface Builder的意图,所以我怀疑我在视图设计期间做了一些根本错误的SDK。此外,在极少数情况下,我不必改变观点,我真的不知道两种设计方法的区别。

另请注意,大多数情况下,我尝试使用IB设计我的视图,并进行一些小的自定义。

在没有这样的代码存根的情况下,有没有其他人遇到这个并知道他们要做什么修复?

5 个答案:

答案 0 :(得分:16)

我已使用Apple's NavBar sample code尝试重现此问题。

applicationDidFinishLaunching最初是这样实现的:

[window addSubview:navigationController.view];
[window makeKeyAndVisible];

如果我将其更改为:

UIViewController *shellController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
[shellController.view addSubview:navigationController.view];
[window addSubview:shellController.view];
[window makeKeyAndVisible];

然后我出现了差距。

但是,如果我只这样做:

UIView *shell = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[shell addSubview:navigationController.view];
[window addSubview:shell];
[window makeKeyAndVisible];

然后一切看起来都很正常。

所以我想如果它的根视图控制器,每个视图控制器都将偏移其视图。但是导航控制器会覆盖此行为以偏移其视图,无论它是否是根视图控制器。因此,我会说你的差距正在出现,因为你的层次结构中的某个导航控制器比预期的要低。

答案 1 :(得分:2)

这里要记住的主要事情是视图控制器将自己设置视图的框架。这是因为视图的可用空间量可能会在应用程序的生命周期内发生变化,并且只有视图控制器知道如何正确调整视图的框架。空间量变化的示例包括导航栏更改高度,将设备从纵向转为横向,并且如果用户正在接听电话,状态栏也可以增加高度。因此,您不应自行修改视图的框架。

因此,您需要做的第一件事就是删除与修改视图框架相关的所有代码。

现在,您需要使用心态来设计视图,框架大小可能随时发生变化。这意味着正确设置每个子视图的自动调整属性。如果你这样做,那么你打开模拟导航和状态栏是否无关紧要;他们只是帮助你看看大多数情况下最终结果会是什么样的。

您可以在尺寸检查器(具有标尺图标的那个)中在Interface Builder中设置每个子视图的自动调整属性。在动画中,白框表示视图控制器的根视图,红框表示当前选定的子视图。您会注意到默认情况下子视图锚定在根视图的左上角。如果视图的大小永远不会改变,这很好,但我们知道这不是真的。如果您想要在底部显示的子视图无关紧要,那么您需要使用左侧的图表。它的工作方式是,如果选择边缘周围的四条线之一,则根视图的边缘与子视图的边缘之间的距离是固定的。因此,如果您希望子视图显示在底部,则需要确保选择最底部的行而不是顶部。中间的两行会影响根视图更改大小时子视图的大小是否会更改。因此,例如,如果您有一个想要占据屏幕整个高度的表视图,则应确保选择了内部垂直线。这被称为支柱和弹簧模型。

如果要以编程方式添加子视图,则需要在每个子视图上设置autoresizingMask属性。 Here's an explanation

希望有所帮助!

答案 2 :(得分:1)

答案 3 :(得分:0)

link text

这里讨论类似的错误。

也是动画设置为NO?尝试将其设置为YES,因为这解决了我遇到的类似问题。

答案 4 :(得分:0)

Moshy的回答非常有用,因为我终于意识到IB中用于控制UIView元素的resize属性的虚线/实线的含义。

然而,调整这些属性并没有解决我遇到的一个类似问题。此视图具有IB中定义的状态和顶部栏。这是一个略重的, 包含一个UIWebView,它将在viewWillAppear和一些其他界面元素中加载HTML字符串。

在加载视图时,如果用户突然将设备的方向从纵向更改为横向,则视图的所有内容都将向下移动状态栏的高度。即使在切换回纵向后,视图控件及其顶部之间的间隙也会保持不变。

最终解决了我的问题,以及我剩下的头发,正在添加一行:

    self.view.frame = [[UIScreen mainScreen] bounds];

中的

-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

自从我的视图内容保持不变,尽管设备方向突然改变。