ペン先からの通話中のステータスバーに応じてビューのサイズを変更するにはどうすればよいですか?
サイズ変更プロパティを設定するだけだと思いましたが、ルートUIViewでは有効になっていません。
(ここでの私の主な問題は、これが何と呼ばれるかわからないことだと思います。シミュレータのメニューコマンドについて説明している場合を除いて、どのドキュメントにも通話中のステータスバーへの参照が見つかりません。)
'サイズ変更プロパティがルートUIViewに対して有効になっていない'とはどういう意味ですか?
通話中のステータスバーには特別な指定はなく、その周りにAPIや通知はないと思います。代わりに、ビューを正しく自動サイズ変更するように設定する必要があります。
Xcodeで新しいナビゲーションベースのアプリを作成し、RootViewController.xibのテーブルビューで自動サイズ変更の設定を調べてみてください。うまくいけば、Appleが設定したものとプロジェクトで設定したものとの間にデルタが見られるでしょう。
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
これは、アプリケーションがバックグラウンドで実行されていて、コマンド+ 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;
}];
}
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];
そうしないと、サブビューのサイズが自動的に変更されませんが、私が知る限り、他の症状はありません。
以前に投稿されたソリューションはどれも私にはうまくいきませんでした。私にとってうまくいったのは、自分のビューに対して制約を適切に設定していなかったことです。私の状況では、ビュー内に2つの異なるコンテナビューがありました。
一番下(リスト内)のコンテナビューはUITableView
でしたが、テーブルの一番下まで正しくスクロールしていませんでした。その理由は、通話中のステータスバーのオフセットにより、UITableView
の起点(左上隅)が変化したが、サイズは同じままだったためです。これは、テーブルの下部が画面外にあることを意味しました。
解決策は、自動サイズ変更高さ制約を正しく設定することでした。以下のスクリーンショットでは、自動サイズ変更ボックスの中央にある垂直矢印です。