如何根据笔尖的通话状态栏调整视图大小?
我认为它只是设置调整大小属性,但没有为根 UIView 启用它们。
(我认为我的主要问题是我不知道其中的任何一个被称为什么;我在任何文档中都找不到对通话状态栏的任何引用,除非它谈到了模拟器菜单命令。)
每当状态栏发生变化时,iOS 都会调用 viewController 的viewWillLayoutSubviews方法。您可以覆盖它并根据新边界调整您的子视图。
- (void)viewWillLayoutSubviews {
// Your adjustments accd to
// viewController.bounds
[super viewWillLayoutSubviews];
}
您正在寻找 -[UIApplication statusBarFrame] 并且在您的 UIApplicationDelegate 中,您应该实现此委托方法以在状态栏的框架发生更改时收到通知:
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame
如果您没有设置根视图控制器,则视图可能不会随着状态栏大小的变化而自动调整大小。我最初在我的应用程序委托中有这个,并且我的应用程序在所有方面都正常工作,除了它在电话期间无法正确调整大小。
[self.window addSubview:rootController.view];
我将上面的行更改为此,现在我的应用程序在通话期间自动调整大小。
[self.window setRootViewController:rootController];
在日志中看到此问题并调查原因后,我发现了此修复程序。
Application windows are expected to have a root view controller at the end of application launch
当我的应用程序在后台运行并且我按 command + T 时,这对我非常有效。在我的场景中,根控制器是我的标签栏控制器,我正在重新调整每个标签内的导航控制器。
- (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame{
[UIView animateWithDuration:0.35 animations:^{
CGRect windowFrame = ((UINavigationController *)((UITabBarController *)self.window.rootViewController).viewControllers[0]).view.frame;
if (newStatusBarFrame.size.height > 20) {
windowFrame.origin.y = newStatusBarFrame.size.height - 20 ;// old status bar frame is 20
}
else{
windowFrame.origin.y = 0.0;
}
((UINavigationController *)((UITabBarController *)self.window.rootViewController).viewControllers[0]).view.frame = windowFrame;
}];
}
当您说“未为根 UIView 启用调整大小属性”时,您是什么意思?
通话状态栏没有任何特别的特殊名称,我认为它周围没有任何 API 或通知。相反,您的视图应该简单地设置为正确自动调整大小。
尝试在 Xcode 中创建一个新的基于导航的应用程序,并研究 RootViewController.xib 中表格视图的自动调整大小设置。希望您会看到 Apple 设置的内容与您在项目中设置的内容之间存在差异。
对于像 UITableView 这样的视图,您通常需要更改表格单元格的高度,除了实现application:didChangeStatusBarFrame:之外没有其他方法可以做到这一点。但这没什么大不了的,如果需要,您可以将行高设置为非整数值。
状态栏变化框的通知是
UIApplicationWillChangeStatusBarFrameNotification
注册为观察员:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(statusBarFrameWillChange:)name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
然后响应处理程序中的更改:
- (void)statusBarFrameWillChange:(NSNotification*)notification
{
// respond to changes
}
即使自动布局设置正确,您也可能需要响应更改。例如,根据屏幕中给定空间计算其单元格高度的表格视图可能需要reloadData
在状态栏更改后进行。
我遇到了同样的问题。我做的是这个。
我希望我很清楚。
如果您以编程方式设置视图框架,则必须手动更新视图
-(void) viewDidAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(statusBarFrameWillChange:)name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
}
- (void)statusBarFrameWillChange:(NSNotification*)notification
{
// respond to changes
NSLog(@"STATUS BAR UPDATED");
NSDictionary *statusBarDetail = [notification userInfo];
NSValue *animationCurve = statusBarDetail[UIApplicationStatusBarFrameUserInfoKey];
CGRect statusBarFrameBeginRect = [animationCurve CGRectValue];
int statusBarHeight = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication]statusBarOrientation])) ? statusBarFrameBeginRect.size.height : statusBarFrameBeginRect.size.width;
NSLog(@"status bar height %d", statusBarHeight);
}
-(void) viewDidDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationBackgroundRefreshStatusDidChangeNotification object:nil];
}
这为您提供了状态栏的新高度,并使用它可以相应地更新您的框架。
解决方案是确保您已经制作了窗口键:
[window makeKeyAndVisible];
如果你不这样做,子视图不会自动调整大小,但据我所知没有其他症状。
之前发布的解决方案都不适合我。对我有用的是我没有为我的观点正确设置约束。在我的情况下,我的视图中有两个不同的容器视图。
底部(在列表中)容器视图是 a UITableView
,它没有正确滚动到表格底部。原因是通话状态栏的偏移量导致原点(左上角)UITableView
发生变化,但大小保持不变。这意味着表格的底部不在屏幕上!
解决方案是正确设置Autoresizing高度约束。在下面的屏幕截图中,它是Autoresizing框中间的垂直箭头。