objective-c iPhone - 关闭模态视图控制器后 - 页面顶部留下间隙
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1272912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IPhone - After dismissing Modal View Controller - gap is left at top of page
提问by Brian
When starting the app, if the user doesn't have login information stored, I want to display a modal view controller to force the entry of this information. I found through trial and error, that this had to occur in viewDidAppear of my root view controller. I tried to put it in viewDidLoad and viewWillAppear, but those didn't work unless I assigned the view of the root view controller to the view of the navigation controller used in the modal which then caused other issues...
启动应用程序时,如果用户没有存储登录信息,我想显示一个模态视图控制器来强制输入此信息。我通过反复试验发现,这必须发生在我的根视图控制器的 viewDidAppear 中。我试图将它放在 viewDidLoad 和 viewWillAppear 中,但是除非我将根视图控制器的视图分配给模式中使用的导航控制器的视图,否则它们不起作用,然后导致其他问题......
So I have:
所以我有:
- (void)viewDidAppear:(BOOL)animated
{
NewAccountViewController *newAccountViewController = [[[NewAccountViewController alloc] initWithNibName:@"NewAccountViewController" bundle:nil] autorelease];
UINavigationController *accountNavigationController = [[UINavigationController alloc] initWithRootViewController:newAccountViewController];
[self presentModalViewController:accountNavigationController animated:YES];
}
And in the newAccountViewController I have a simple navigation item button that dismisses the modal view controller with dismissModalViewController.
在 newAccountViewController 中,我有一个简单的导航项按钮,它使用dismissModalViewController 关闭模态视图控制器。
This all works and when the modal is dismissed a view in a navigation controller is visible with its navigation item title at the top....
这一切都有效,当模态被解除时,导航控制器中的视图可见,其导航项标题位于顶部....
But there is a white gap about the same size as the status bar between the status bar and the top of the blue navigation item bar. If I don't do the modal, then the gap is never there. It only occurs after the modal is presented and dismissed. I've tried doing animated:NO on both the present and dismissModalViewController. I've also tried not using the navigation controller in the modal, and that did nothing as well. Any ideas would be great! Thanks.
但是状态栏和蓝色导航项栏的顶部之间有一个与状态栏大小相同的白色间隙。如果我不做模态,那么差距就永远不会存在。它只发生在模态出现和消失之后。我试过在present和dismissModalViewController上做animated:NO。我也试过不在模态中使用导航控制器,但也没有做任何事情。任何想法都会很棒!谢谢。
采纳答案by Brian
Turns out this was happening because I was calling my modalviewcontroller on the current view controller, but my view controller already had a another view controller loaded as a subview. Once I changed it to make the view controller in the subview, load the modal, then it went away. Thanks for all your help.
原来这是因为我在当前视图控制器上调用了我的 modalviewcontroller,但是我的视图控制器已经有另一个视图控制器作为子视图加载了。一旦我更改它以在子视图中创建视图控制器,加载模态,然后它就消失了。感谢你的帮助。
回答by Tyler
I had the same problem. My solution was to temporarily close the status bar just before switching views:
我有同样的问题。我的解决方案是在切换视图之前暂时关闭状态栏:
- (void) temporarilyHideStatusBar {
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self performSelector:@selector(showStatusBar) withObject:nil afterDelay:0];
}
- (void) showStatusBar {
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
// Use these by calling the hide function just before a broken view switch:
[self temporarilyHideStatusBar];
[self doViewSwitch];
// No need to call [self showStatusBar]; explicitly.
I experimented with other code-based solutions, and I like this one the best because it works 100% of the time - some of my frame-based solutions only worked mostof the time - and because it has minimal user-visible effects.
我尝试了其他基于代码的解决方案,我最喜欢这个解决方案,因为它 100% 的时间都有效——我的一些基于帧的解决方案只在大部分时间有效——而且因为它对用户可见的影响最小。
I suspect this is an Apple bug, and it would be nice to hear the official word from them on the best workaround.
我怀疑这是 Apple 的错误,很高兴听到他们关于最佳解决方法的官方消息。
回答by Mark
I ran into the same issue. Not sure what causes it, but I fixed it with the following line of code just after I dismiss my modal view:
我遇到了同样的问题。不知道是什么原因造成的,但我在关闭模态视图后使用以下代码行修复了它:
[self.view setFrame:CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height)];
Just adjust the Y offset to meet your needs. In another instance I had to make it 20 instead of 10.
只需调整 Y 偏移即可满足您的需求。在另一个例子中,我不得不把它变成 20 而不是 10。
回答by nomad00
Just wanted to chime and say I had the exact opposite problem - a white gap at the bottomof the screen. And the fix was also the opposite, I was presenting from a subview, when I needed to be presenting from the parent. Thanks!
只是想提醒一下,我遇到了完全相反的问题 -屏幕底部有一个白色间隙。而修复也是相反的,当我需要从父视图呈现时,我是从子视图呈现的。谢谢!
回答by Darren
In case anyone looks at this post (I did today and so others might). I am a newbie to objective c but and you may laugh at my suggestion but here goes.
万一有人看到这篇文章(我今天做了,所以其他人可能会看到)。我是目标 c 的新手,但你可能会嘲笑我的建议,但这里是。
When running my iPad app the status bar was always overlapping my form. I wasn't happy to use the method for changing the frame coordinate down 20px so went searching.
运行我的 iPad 应用程序时,状态栏总是与我的表单重叠。我不喜欢使用将框架坐标向下更改 20px 的方法,所以开始搜索。
Found that if I was to assign my custom view controller to the window rootViewController then the status bar overlap problem went away. I haven't tried the modal stuff in this post but hope this helps other newbies who may be wondering how to sole this problem.
发现如果我将我的自定义视图控制器分配给窗口 rootViewController 那么状态栏重叠问题就消失了。我还没有尝试过这篇文章中的模态内容,但希望这可以帮助其他可能想知道如何解决这个问题的新手。
This is what a simple AppDelegate didFinishLaunchingWithOptions method would look like:
这是一个简单的 AppDelegate didFinishLaunchingWithOptions 方法的样子:
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
TEGGameViewController *gameVC = [[TEGGameViewController alloc] init];
self.window.rootViewController = gameVC;
[self.window makeKeyAndVisible];
return YES;
}
回答by Alexey Kozhevnikov
The given answer is hard to understand, more like a vague hint, so it's a try to explain more detailed:
给出的答案很难理解,更像是一个模糊的提示,所以尝试更详细地解释:
The problem is that the root view controller which viewDidAppear:method is presented in the question looks like to a be simple UIViewController. And how we can see in Apple's documentation for wantsFullScreenLayout:
问题是问题中提供的viewDidAppear:方法的根视图控制器看起来很简单UIViewController。以及我们如何在 Apple 的文档中看到wantsFullScreenLayout:
The default value of this property is NO, which causes the view to be laid out so it does not underlap the status bar
此属性的默认值是 NO,这会导致视图布局,因此它不会与状态栏重叠
This root view controller presents UINavigationControllermodally, so presented navigation controller uses not the whole screen. Also it seems that default UINavigationController's value for wantsFullScreenLayoutis YES. That's why navigation controller adds the gap — to avoid underlapping the status bar with navigation bar.
这个根视图控制器以UINavigationController模态方式呈现,因此呈现的导航控制器不使用整个屏幕。此外,它似乎是默认UINavigationController的为价值wantsFullScreenLayout就是YES。这就是导航控制器添加间隙的原因——避免状态栏与导航栏重叠。
So there are several ways to solve it:
所以有几种方法可以解决:
1) Present navigation controller with wantsFullScreenLayoutproperty set to NO. (Or to present ~fresh UIViewController with a UINavigationController's view as a subview)
1) 将wantsFullScreenLayout属性设置为 NO 的当前导航控制器。(或将 ~fresh UIViewController 与 aUINavigationController的视图作为子视图呈现)
2) Change the rootViewControllerproperty of UIWindowto navigation controller manually, so navigation controller is presented on the whole window. Can use it e.g. when the first screen is kind of disposable pin/password input, and we can easily drop it after successful login and change for navigation controller.
2)手动更改导航控制器的rootViewController属性UIWindow,使导航控制器呈现在整个窗口上。可以使用它,例如当第一个屏幕是一次性密码/密码输入时,我们可以在成功登录后轻松删除它并更改导航控制器。
回答by Steve
I had the exact same problem... my solution? Manually set the height of the view you're displaying modally to 480 px in interface builder.
我遇到了完全相同的问题……我的解决方案?在界面构建器中手动将您以模态显示的视图的高度设置为 480 像素。
Problem solved.
问题解决了。
回答by Daniel
OK, I do not know why this happens, it happened to me though and ill tell you how i fixed it. I found that adding a view at 0,0 made it overlap with the status bar...this is weird because before 3.0 I never had projects do this behavior 0,0 was always underneath the status bar. Anyway so I saw that it was overlapping so i started putting my views at 0,20 or however big the status bar is. That was cool until I tried using a modal view controller, when it dismissed i found the gap the size of the status bar (what you are expiriencing), for some reason the modal view thinks 0,0 DOES NOT overlap the status bar and when it dismisses 0,20 (of your previous view) shows up as if (0,0) does not over lap and (0,20) has the extra white gap. Why did this start happening ? No clue. Anyway to fix it i knew i had to fix the whole overlap of the view and status bar at 0,0 thing. I kept trying but nothing, then I decided to try to create a new View based project in xcode (which sets up the initial view for you) and see if their view overlaps (or if they put it at 0,20), what i found is that it DID NOT overlap and 0,0 was the right placing, right below the status bar and not overlapping it. Bizzare? i think so. So what i did on my project was copy the set up they had in the newly created view based project (they set the viewControllers property through Interface Builder, you can create a view based project like I did and just mimic their set up), i found that this fixed the issue, views at 0,0 no longer overlapped the status bar and dismissing modal view controllers no longer left the gap. Dont know if this is your case, but it might be, hopefully this will help you.
好吧,我不知道为什么会发生这种情况,但它发生在我身上,我会告诉你我是如何修复它的。我发现在 0,0 处添加视图使其与状态栏重叠...这很奇怪,因为在 3.0 之前我从未有项目执行此行为 0,0 总是在状态栏下方。无论如何,所以我看到它是重叠的,所以我开始将我的视图放在 0,20 或状态栏有多大。这很酷,直到我尝试使用模态视图控制器,当它关闭时,我发现状态栏的大小(您正在经历的)的差距,出于某种原因,模态视图认为 0,0 不与状态栏重叠,当它消除了 0,20(您之前的视图)显示为好像 (0,0) 没有重叠并且 (0,20) 具有额外的白色间隙。为什么会这样?没有线索。无论如何要修复它,我知道我必须将视图和状态栏的整个重叠修复为 0,0。我一直在尝试但什么也没做,然后我决定尝试在 xcode 中创建一个基于视图的新项目(它为您设置初始视图)并查看他们的视图是否重叠(或者他们是否将其放在 0,20),我发现它没有重叠并且 0,0 是正确的放置,就在状态栏的正下方并且没有重叠。奇葩?我想是这样。所以我在我的项目中所做的是复制他们在新创建的基于视图的项目中的设置(他们通过 Interface Builder 设置了 viewControllers 属性,你可以像我一样创建一个基于视图的项目,只是模仿他们的设置),我发现这解决了这个问题,0,0 处的视图不再与状态栏重叠,并且关闭模态视图控制器不再留下间隙。不知道你是不是这种情况
回答by jimiHendrix
I am running into the same problem. I admit that I may have taken a nontraditional route, embedding a tab bar in a NavController, and now I'm kinda seeing why they say not to do it. Well, whatever, it makes sense for my app, even if it is a total pain to implement.
我遇到了同样的问题。我承认我可能采取了非传统的路线,在 NavController 中嵌入了一个标签栏,现在我有点明白为什么他们说不要这样做。好吧,无论如何,这对我的应用程序来说是有意义的,即使实施起来很痛苦。
My problem is that once I pushed a Modal VC onto a TabController subview (which is, in turn, a subview of the overarching NavController View, which has control of the top NavBar... which turns into a delegation nightmare) and then dismiss the MVC, the view that comes back is pushed up under the NavBar. Doesn't happen when I add or push any other subviews, just with MVCs.
我的问题是,一旦我将 Modal VC 推送到 TabController 子视图(反过来,它又是总体 NavController 视图的子视图,它可以控制顶部 NavBar ......这变成了委托噩梦)然后关闭MVC,返回的视图被推到 NavBar 下。当我添加或推送任何其他子视图时不会发生,只是使用 MVC。
[self.view setFrame:(CGRect)] does seem to do the trick, if I call it right after [self dismissModal...]. However, it has to be called on all subviews of my tab bar controller, or even the other lists are shunted up under the bar. Poopy.
[self.view setFrame:(CGRect)] 似乎确实可以解决问题,如果我在 [self deniedModal...] 之后立即调用它。但是,它必须在我的标签栏控制器的所有子视图上调用,或者甚至其他列表都在栏下分流。便便。
Makes things a headache, but not unsolvable. But I agree, this is a new bug with 3.x (or maybe it's one of those double-edged "new features"), and it's downright annoying. I'm downloading 3.1.2 SDK now, and hopefully it addresses this. Gonna comment my [setFrame] lines and see what happens. But hopefully, if it's not solved in this version, it will be soon. Until then, it seems that the solution is a lot of (admittedly hackerish and repetitive) code.
使事情头疼,但并非无法解决。但我同意,这是 3.x 的一个新错误(或者它可能是那些双刃剑的“新功能”之一),而且非常烦人。我现在正在下载 3.1.2 SDK,希望它能解决这个问题。将评论我的 [setFrame] 行,看看会发生什么。但希望,如果它在这个版本中没有解决,很快就会解决。在那之前,似乎解决方案是大量(不可否认的黑客和重复)代码。
EDIT: Nope, updating didn't help. Poop. Back to the code I go, to hard-define the position of every screen. Awesome. Hopefully the size of Nav and Tab Bars doesn't ever change.
编辑:不,更新没有帮助。船尾。回到我去的代码,硬定义每个屏幕的位置。惊人的。希望导航栏和标签栏的大小永远不会改变。
EDIT 2: Hey! I solved it! (i R prowd.) Seems the problem was that, when my MVC was dismissed, my view got passed back to the tab bar controller, which had "forgotten" it had a nav bar above it. Don't tell me how, I'm probably way out of documented territory by now. But, I solved my particular problem by simply redefining the [subview.view setFrame:0,0,width, height] after returning from editing. Not sure why this made anydifference, but in the app it did, because no longer is the first one and a half rows of my table view sneaking up under the nav bar. So I really have no advice, just find the right place to put
编辑2:嘿!我解决了!(i R prowd。) 似乎问题是,当我的 MVC 被解雇时,我的视图被传递回标签栏控制器,它“忘记”了它上面有一个导航栏。不要告诉我如何,我现在可能已经超出了记录的领域。但是,我通过在编辑返回后简单地重新定义 [subview.view setFrame:0,0,width, height] 来解决我的特定问题。不知道为什么这有什么不同,但在应用程序中确实如此,因为不再是我的表格视图的第一行半行在导航栏下偷偷摸摸。所以我真的没有建议,只是找个合适的地方放
[(appropriateViewController).view setFrame:CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height];
[(appropriateViewController).view setFrame:CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height];
Not sure why it works but it does. Isn't that the worst kind of error?
不知道为什么它有效,但确实如此。这不是最糟糕的错误吗?
回答by Rob
I used @Mark Hammonds answer, but simply reset the frame's offset to 0, ie:
我使用了@Mark Hammonds 的答案,但只需将帧的偏移量重置为 0,即:
// this won't be called on the parent view if a modal dialog is dismissed. [self.parentViewController viewWillAppear: animated];
// actually dismiss the modal dialog.
[[TOSplitViewController active] dismissModalViewControllerAnimated: animated];
// fix the mysterious white bar that appeared on the top.
[[TOSplitViewController active].view setFrame:CGRectMake(0,0, [TOSplitViewController active].view.frame.size.width, [TOSplitViewController active].view.frame.size.height)];
As you might guess, this was while trying to dismiss a modal dialog presented on top of a split view on an iPad application.
正如您可能猜到的,这是在尝试关闭显示在 iPad 应用程序拆分视图顶部的模式对话框时。
I did try @Tyler's answer, and it didn't work for me.
我确实尝试过@Tyler 的回答,但对我不起作用。
This on iOS4.1, targeting iPad 3.2.
这在 iOS4.1 上,针对 iPad 3.2。

