質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Q&A

解決済

1回答

3965閲覧

<Objective-c>viewControllerのview領域がnavigationBarよりも上に設定できない

deltaZone

総合スコア12

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

0グッド

0クリップ

投稿2015/09/01 12:37

編集2015/09/10 05:05

objective-cのステータスバー及びナビゲーションバーについて質問させてください。

▶︎navigationBarとstatusBarを透過にして任意の画像を共通の背景に設定する、
もしくは
▶︎statusBarの領域にnavigationBarの背景を共有する、
のいずれかが実現したいのですが
navigationControllerによって管理されているviewController上に
スクロールビューやCollectionViewを使ってviewを作ると

イメージ説明

のような状態になり、statusBar領域には最背面のwindowの色が反映され、
navigationBarと分離された状態になってしまいます。さらにviewControllerのビュー領域がnavigationBarより上に潜り込みません。

該当のviewControllerのviewDidLoad内では

self.automaticallyAdjustsScrollViewInsets = NO; [self setEdgesForExtendedLayout:UIRectEdgeNone];

を設定し、
storyBoardでは
adjust scroll view insets のチェックを外す
under top barのチェックを入れる
という設定を試しましたが、うまくいきません。

EdgesForExtendedLayoutやcontentInsetsの基本的なことも
覚束ないので、指南していただければ助かります。

補足:
NavigationControllerは

[[UINavigationBar appearance] setBackgroundImage:[UIImage new] forBarPosition:UIBarPositionTopAttached barMetrics:UIBarMetricsD efault]; [[UINavigationBar appearance] setFrame:CGRectMake(0,0,[UIScreen mainScreen].bounds.size.width, 64)]; [[UINavigationBar appearance] setShadowImage:[UIImage new]]; [[UINavigationBar appearance] setTranslucent:YES]; [[UINavigationBar appearance] setBackgroundColor:[UIColor clearColor]];

のように透過させています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Stripe

2015/09/03 16:11

ところで、なぜnavigationBarをstatusBarの領域に表示させたいんですか?通常であれば、むしろ困ると思うんですけど?
deltaZone

2015/09/03 16:56

現在は追加した画像のように背景が分かれているんですが、 各ボタンやラベルを残して、背景に統一感を出したいと考えています。 一言で言えばデザインの観点からです。
guest

回答1

0

ベストアンサー

ステータスバーの背景色はもともと透明ですが、ナビゲーションバーの背景はデフォルトで曇りガラス状になっているのをどうやって透明にしているんですか?
もし、ナビゲーションバーの背景画像に透明の画像を貼り付けることでコンテンツを透過させているんだったら、その画像の縦サイズを確認してみてください。もし縦サイズが44ピクセル(@2xで88ピクセル)なら、質問にあるようにステータスバーの部分に背景画像が適用されず、黒く表示される現象が発生します。ナビゲーションバーに背景画像を貼る場合、ステータスバーの部分も含めた縦64ピクセル(@2xで128ピクセル)の画像が必要です。

以下のURLで最高得票を得られた回答の4,5あたりをよく読んでみてください。
http://stackoverflow.com/questions/18294872/ios-7-status-bar-back-to-ios-6-default-style-in-iphone-app

もし透明画像を使わずにナビゲーションバーを透明にしているのでしたら、どうやって透明にしているか補足ください。

Adjust Scroll View InsetsやExtended Edgesについては、
まずviewDidLoad内で設定した

self.automaticallyAdjustsScrollViewInsets = NO;
[self setEdgesForExtendedLayout:UIRectEdgeNone];


storyBoardで設定した

adjust scroll view insets のチェックを外す
under top barのチェックを入れる

は、同じものを設定しており、両方で設定した場合はまずstoryBoardから
読み込んだ値を適用してロードし、その後すぐviewDidLoadの設定で
上書きされると認識してください。

その上で以下のURLの解説を読んでみることをお勧めします。
http://qiita.com/yimajo/items/254c7cebab7864678246

今回の場合、ナビゲーションバーにViewControllerのビューを潜り込ませたいのですから
edgesForExtendedLayoutはUIRectEdgeTopの指定が必須です。

automaticallyAdjustsScrollViewInsetsについては、
スクロールアップした時にコンテンツの開始位置がナビゲーションバーと
重ならないようにしたければYESにすればいいし、
画面の一番上(ステータスバーと重なる部分)がコンテンツの開始位置
となるようにしたければNOを設定すればいいです。
複雑な画面ならAutoAdjustに頼るのではなく、自分で意図するレイアウトになるよう
scrollViewInsetsを自分で調整した方がよいかもしれません。


(9/10追記)

透明にする方法について補足と疑問点についてコメントを頂いたので追記します。

まず、透明にする方法についてですが

[[UINavigationBar appearance] setBackgroundImage:[UIImage new] forBarPosition:UIBarPositionTopAttached barMetrics:UIBarMetricsDefault];

setBackgroundImageで[UIImage new]を指定しているということは、0x0サイズの画像を
背景画像として貼り付けているということです。
私は0x0サイズの画像をナビゲーションバーに貼り付けたことはなかったので、どうなるか確認してみた
ところ、ステータスバーの部分は黒くならず、一番下に重なっているスクロールビューのコンテンツが
表示されました。つまり私のテスト環境では意図通り動作しました。
ただ、0x0サイズの画像というのはとても特殊なので、環境によって変わる不定動作を引き起こすのかもしれません。
念のため縦64ピクセルの透明画像を貼り付けて試してみた方がよいように思います。
縦64ピクセルの透明画像を貼り付けるには、
UIGraphicsBeginImageContextWithOptions(CGSizeMake(320, 64), NO, 0);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
で、imageを作成し、[UIImage new]の替わりにimageを指定すればよいです。

次にコメントに書かれている疑問点についてですが、
まず、「scrollViewInsets」と書いているのは「UIScrollViewクラスのcontentInset」の誤りです。うろおぼえのままちゃんと確認せず書いてしまいました。すみません。contentInset.topを指定するという認識で正しいです。
ただ、今回の問題(ステータスバーの部分が黒くなる)は、contentInsetの設定とは関係ないと思います。まずはステータスバーの部分が黒くなる問題を解消してから、contentInset.top(スクロールエリアの余白)は後で調整したのでよいと思います。

投稿2015/09/07 14:35

編集2015/09/10 08:08
TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

deltaZone

2015/09/10 06:31

本文に透過についての補足をしました。 UIRectEdgeTopを設定しましたが解消できません。 scrollViewInsetsの設定はどのようにやるのでしょう? おかしい所がスクロールビューまたはそのサブクラスを使っている所だけで、 教えていただいたqiitaのurl等からもcontentInsets.topの設定かなと想像しているのですが、scrollViewInsetsの設定するということはcontentInsets.topを設定するということと同じなんでしょうか。これらの設定方法が分かりません。。
TakeOne

2015/09/10 08:09

頂いた補足に対応して回答を追記しましたので確認ください。
deltaZone

2015/09/10 12:11 編集

大変わかりやすくて助かります。 言われた方法を試しましたが、結果が変わりません。 度々コメントにて質問してしまい申し訳有りませんが、 appDelegate内のdidFinishLaunchingWithOptionsで self.windowの背景色を変えたところ、ステータスバーがwindowの背景色と同じになる事が新しくわかったのですが、これはunderTopBar(UIRectEdgeTop)がステータスバーに対してきいてない、ということなのでしょうか?
TakeOne

2015/09/10 15:41

ステータスバーがwindowの背景色と同じになるということなら、私が指摘した透明画像の縦サイズの問題とは別件になります。縦サイズを44ピクセルにした時は、ステータスバー部分の残り20ピクセルは(windowsの背景色でなく)常に黒になります。 おそらくなんらかの原因でViewControllerのビューが20ピクセル下から表示されているのではないかという気がしますが、どのようにしたらそういう状況になるのか推測するのは難しいです。例えばUINavigationControllerの設定でナビゲーションバーの表示をOFFにし、別途自分でナビゲーションバーを貼り付けたりしていませんよね? とりあえず、「Master-Detail Application」テンプレートを使った新規プロジェクトを作成し、それにあなたが提示した透明化コードをAppDelegate内のdidFinishLaunchingWithOptionsに加えるだけで、ちゃんとステータスバーもナビゲーションバーも透明になって、下に重なったスクロールビューが透過表示されるアプリが作れるはずです。それを自分で作って確認した上で、自分のプロジェクトとどう違うか差異を分析すれば何か原因がわかるかもしれません。
deltaZone

2015/10/17 10:11

takeOneさんの回答からrecursiveDescriptionでviewControllerの階層構造を調べたところ、 確かにViewControllerのビューが20ピクセル下から表示されている、とわかったので さらに調べたところ 一定の条件を満たしたUIViewControllerのスクロールビューに対して、自動的にcontentInsetsが付与されることがわかりました。 (http://qiita.com/glayash/items/b759bd1da0aedf8adc82) このinsetsはsubViewsにも影響するものらしく それまでストーリーボード間で同じnavigationControllerを使っていたので、 ストーリーボード毎に新しいnavigationControllerを用意し、その中で明示的にframeの座標に(0,0)を指定をしたところ、それ以降のviewControllerが(0,0)座標に表示できて 任意のviewImageをつかってstatusBar/navigationBarの背景にすることができました。 どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問