简体   繁体   English

由于方向/摇晃,UINavigationController 加载视图不正确

[英]UINavigationController loading view incorrectly due to Orientation/Shake

Background: App has a shake to go home feature.背景:应用程序对 go 主页功能有震动。 Home view Only supports portrait.主页视图 仅支持纵向。 If you shake a bit harder than usual, the view that you are on starts to rotate (which is fine), but then it detects a shake and does a popViewControlller to the home view.如果您比平时更用力地摇晃,您所在的视图会开始旋转(这很好),但随后它会检测到摇晃并对主视图执行 popViewController。 When it does this it loads the navigation controller just fine, but the view under (the home content) gets loaded behind the bar and is stretched up (it's basically loading underneath the navigation bar, so it gets stretched up)当它这样做时,它会加载导航 controller 就好了,但是(主页内容)下的视图被加载到栏后面并被拉伸(它基本上是在导航栏下面加载,所以它被拉伸了)

The back button handles this just fine from landscape to portrait (since its not mid transitions)后退按钮可以很好地处理从横向到纵向的处理(因为它不是中间过渡)

How should I go about handling this orientation change (from the shake) so I can pop back into the root view controller, without the view loading under the navigation bar?我应该如何 go 处理这种方向变化(从摇动),以便我可以弹回根视图 controller,而不在导航栏下加载视图?

Edit:What's happening is the content thinks that it has the entire view to load, so it stretches itself to take the entire screen, not realizing theres a navigationbar above it.编辑:发生的事情是内容认为它有整个视图要加载,所以它会伸展自己以占据整个屏幕,而没有意识到它上面有一个导航栏。 I can tell since the images loading are stretched out我可以知道,因为加载的图像被拉伸了

added a bounty of 50.增加了50的赏金。

Edit Here's How I'm detecting Shakes and Popping编辑这是我检测震动和爆裂的方式

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{

    if ( event.subtype == UIEventSubtypeMotionShake )
    {

            UINavigationController *navController = self.navigationController;

            [[self retain] autorelease];
            HomeViewController *home = [[HomeViewController alloc]init];
            [navController popViewControllerAnimated:YES];

            home.title =@"Home View Controller";
            [home release];     
        }

    if ( [super respondsToSelector:@selector(motionEnded:withEvent:)] )
        [super motionEnded:motion withEvent:event];
}

Here's my App Delegate:这是我的应用程序代表:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    navController = [[UINavigationController alloc]init];
    [self.window addSubview:navController.view];

    HomeViewController *home = [[HomeViewController alloc]init];
    [[self home] setFrame:[[UIScreen mainScreen] applicationFrame]];

I'll include a mockup here.我将在这里包含一个模型。

Normal View:普通视图:

普通视图

Stretched View After a Shake/Pop:摇晃/弹出后的拉伸视图:

拉伸

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return YES;
}

Have you tried calling [[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait animated:YES];您是否尝试过调用[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait animated:YES]; in your home view controller?在您的主页上查看 controller? You could also try to place this in where you detect a shake.你也可以试着把它放在你检测到震动的地方。

in your home view controller's xib, go to the inspector for the view and set top bar as navigation bar.. and in view did load set self.navigationBarHidden = NO;在您的主视图控制器的 xib 中,go 到inspector器的视图并将顶部栏设置为导航栏.. 并且在视图中确实加载了 set self.navigationBarHidden = NO; ... ...

NOTE: there are many thing wrong with the code you've posted.. but none of them causes the orientation problem... in fact this seems to be the only code you need in that method:注意:您发布的代码有很多问题......但它们都不会导致方向问题......事实上,这似乎是您在该方法中需要的唯一代码:

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (event.subtype == UIEventSubtypeMotionShake)
    {
        [navController popViewControllerAnimated:YES];
    }
}

so you might want to change this code as well..所以您可能也想更改此代码..

I have come across this issue with underlapping the navigation bar.我遇到了与导航栏重叠的问题。 I am not sure what causes it but you can work around it by calling,我不确定是什么原因造成的,但你可以通过调用来解决它,

[[self loadingView] setFrame:[[UIScreen mainScreen] applicationFrame]];

after the problem view is added to window in the application delegate.在应用程序委托中将问题视图添加到 window 之后。

I'm a bit puzzled by your code so I'd really suggest starting from the beginning.我对你的代码有点困惑,所以我真的建议从头开始。 As Lukya mentioned, there's no reason to recreate the HomeViewController.正如 Lukya 所提到的,没有理由重新创建 HomeViewController。 I'm also baffled by the "[[self retain] autorelease];"我也对“[[self retain] autorelease];”感到困惑。 bit.少量。 That shouldn't be necessary unless you're doing something incorrectly elsewhere.除非您在其他地方做错了事情,否则这不是必需的。

So I would start with this... In application:didFinishLaunchingWithOptions: do something like this:所以我会从这个开始......在 application:didFinishLaunchingWithOptions: 做这样的事情:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    {
        HomeViewController *home = [[[HomeViewController alloc] init] autorelease];
        UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:home] autorelease];
        [self.window addSubview:navController.view];
    }

The window will retain a your nav controller and the nav controller will retain your HomeViewController. window 将保留您的导航 controller 和导航 controller 将保留您的 HomeViewController。

Then in motionEnded:withEvent: do something like:然后在 motionEnded:withEvent: 中执行以下操作:

    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if (event.subtype == UIEventSubtypeMotionShake)
        {
            [self.navigationController popViewControllerAnimated:YES];
        }
    }

That should be it.应该是这样的。

If that does not work then can you give any other info?如果这不起作用,那么您可以提供任何其他信息吗? For example, does HomeViewController implement (and return YES) in shouldAutorotateToInterfaceOrientation:?例如, HomeViewController 是否在 shouldAutorotateToInterfaceOrientation: 中实现(并返回 YES)? If so, can you return no so it doesn't rotate since your first line says "Home view Only supports portrait"?如果是这样,你能不能返回 no 所以它不会旋转,因为你的第一行说“主视图只支持纵向”?

Edit: An example of willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation: as well.编辑: willRotateToInterfaceOrientation:duration:didRotateFromInterfaceOrientation:的一个例子。

In the header for whatever controller you're detecting shakes in add a boolean:在 header 中,对于任何 controller,您检测到抖动时添加 boolean:


    BOOL isRotating;

In your implementation file add the two UIViewController methods we want to override -- something like:在您的实现文件中添加我们想要覆盖的两个 UIViewController 方法——类似于:


    - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
        isRotating = YES;
    }

    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
        [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
        isRotating = NO;
    }

Now, do something like this for your event handler:现在,为您的事件处理程序做这样的事情:

    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if (event.subtype == UIEventSubtypeMotionShake && !isRotating)
        {
            [self.navigationController popViewControllerAnimated:YES];
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM