由于方向/晃动,UINavigationController 加载视图不正确
背景: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:
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我对你的代码有点困惑,所以我真的建议从头开始。正如 Lukya 提到的,没有理由重新创建 HomeViewController。我也对“[[自我保留]自动释放];”感到困惑少量。除非您在其他地方做错了什么,否则这应该是没有必要的。
所以我会从这个开始......在 application:didFinishLaunchingWithOptions: 中执行如下操作:
窗口将保留您的导航控制器,导航控制器将保留您的 HomeViewController。
然后在motionEnded:withEvent:中做类似的事情:
应该是这样。
如果这不起作用那么你能提供任何其他信息吗?例如,HomeViewController 是否在 shouldAutorotateToInterfaceOrientation: 中实现(并返回 YES)?如果是这样,您能否返回“否”,以便它不会旋转,因为您的第一行显示“主视图仅支持纵向”?
编辑:还有
willRotateToInterfaceOrientation:duration:
和didRotateFromInterfaceOrientation:
的示例。在您检测到抖动的任何控制器的标头中添加一个布尔值:
在您的实现文件中添加我们想要覆盖的两个 UIViewController 方法 - 类似于:
现在,为您的事件处理程序执行类似的操作:
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:
The window will retain a your nav controller and the nav controller will retain your HomeViewController.
Then in motionEnded:withEvent: do something like:
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:
anddidRotateFromInterfaceOrientation:
as well.In the header for whatever controller you're detecting shakes in add a boolean:
In your implementation file add the two UIViewController methods we want to override -- something like:
Now, do something like this for your event handler:
在主视图控制器的 xib 中,转到视图的检查器并将顶部栏设置为导航栏。并且在视图中加载设置 self.navigationBarHidden = NO;。 ..
笔记:
您发布的代码有很多问题..但它们都不会导致方向问题...事实上,这似乎是该方法中您需要的唯一代码:
所以您可能也想更改此代码..
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 setself.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:
so you might want to change this code as well..
您是否尝试过在主视图控制器中调用
[[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.我在导航栏下重叠时遇到了这个问题。我不确定是什么原因导致它,但
在问题视图添加到应用程序委托中的窗口后,您可以通过调用来解决它。
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,
after the problem view is added to window in the application delegate.