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

发布于 2024-11-23 15:15:00 字数 2008 浏览 2 评论 0原文

背景:App有摇一摇回家功能。主视图仅支持纵向。 如果您比平时摇动得更厉害,您所在的视图就会开始旋转(这很好),但随后它会检测到摇动并对主视图执行 popViewController 操作。当它这样做时,它加载导航控制器就很好,但是(主页内容)下面的视图被加载到栏后面并被拉伸(它基本上加载到导航栏下面,所以它被拉伸)

后退按钮处理这个从横向到纵向就很好(因为它不是中间过渡)

我应该如何处理这个方向变化(从摇动),以便我可以弹回根视图控制器,而无需在导航栏下加载视图?

编辑:发生的情况是内容认为它有整个视图要加载,因此它会拉伸自己以占据整个屏幕,而没有意识到它上面有一个导航栏。我可以看出,因为图像加载被拉伸,

增加了 50 的赏金。

编辑以下是我检测摇动和爆裂的方式

- (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];
}

这是我的应用程序代理:

    - (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]];

我将在此处包含一个模型。

普通视图:

普通视图

摇动/弹出后的拉伸视图:

拉伸

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

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

Background: App has a shake to go home feature. 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. 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)

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?

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.

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:

Normal View

Stretched View After a Shake/Pop:

Streched

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅忆 2024-11-30 15:15:00

我对你的代码有点困惑,所以我真的建议从头开始。正如 Lukya 提到的,没有理由重新创建 HomeViewController。我也对“[[自我保留]自动释放];”感到困惑少量。除非您在其他地方做错了什么,否则这应该是没有必要的。

所以我会从这个开始......在 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];
    }

窗口将保留您的导航控制器,导航控制器将保留您的 HomeViewController。

然后在motionEnded:withEvent:中做类似的事情:

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

应该是这样。

如果这不起作用那么你能提供任何其他信息吗?例如,HomeViewController 是否在 shouldAutorotateToInterfaceOrientation: 中实现(并返回 YES)?如果是这样,您能否返回“否”,以便它不会旋转,因为您的第一行显示“主视图仅支持纵向”?

编辑:还有 willRotateToInterfaceOrientation:duration:didRotateFromInterfaceOrientation: 的示例。

在您检测到抖动的任何控制器的标头中添加一个布尔值:

    BOOL isRotating;

在您的实现文件中添加我们想要覆盖的两个 UIViewController 方法 - 类似于:

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

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

现在,为您的事件处理程序执行类似的操作:

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

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. I'm also baffled by the "[[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:

    - (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.

Then in motionEnded:withEvent: do something like:

    - (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:? If so, can you return no so it doesn't rotate since your first line says "Home view Only supports portrait"?

Edit: An example of willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation: as well.

In the header for whatever controller you're detecting shakes in add a boolean:

    BOOL isRotating;

In your implementation file add the two UIViewController methods we want to override -- something like:

    - (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];
        }
    }
百变从容 2024-11-30 15:15:00

在主视图控制器的 xib 中,转到视图的检查器并将顶部栏设置为导航栏。并且在视图中加载设置 self.navigationBarHidden = NO;。 ..

笔记:
您发布的代码有很多问题..但它们都不会导致方向问题...事实上,这似乎是该方法中您需要的唯一代码:

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

所以您可能也想更改此代码..

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;...

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..

天暗了我发光 2024-11-30 15:15:00

您是否尝试过在主视图控制器中调用 [[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortraitAnimated:YES]; ?您也可以尝试将其放置在检测到震动的地方。

Have you tried calling [[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait animated:YES]; in your home view controller? You could also try to place this in where you detect a shake.

无法回应 2024-11-30 15:15:00

我在导航栏下重叠时遇到了这个问题。我不确定是什么原因导致它,但

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

在问题视图添加到应用程序委托中的窗口后,您可以通过调用来解决它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文