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

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

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2075閲覧

スワイプで左から出てくるスライドメニュー使用時に、NavigationViewがうまく表示されない

eleele28

総合スコア18

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/11/03 06:41

前提・実現したいこと

SwiftUIにて画面を作成しています。
画面左端から右にスワイプを行うとせりだしてくるタイプのサイドメニューのバックにNavigationViewを用いたメインコンテンツを表示し、
サイドメニューでの操作によってNavigationView内のコンテンツの移動などを実現したいと考えています。

↓実現イメージ
イメージ説明

発生している問題・エラーメッセージ

ZStack内にメインコンテンツ(NavigationView内)とサイドメニュー用のViewを配置して実行したところ、以下の問題点が発生しました。

画像①のように、最初に真っ白な背景が表示されてしまいます。本当はメインコンテンツのビューが初期から表示されるようにしたいと考えています。

左上の「<」を押下することでメインコンテンツのビューは表示されるものの、画像②のようにサイドメニューとほぼ同じ大きさの細い表示となってしまっています。

NavigationViewを初期から画面いっぱいに表示するにはどのような方法をとればよいのでしょうか?

↓画像①:画面初期状態。真っ白。本来はメインコンテンツのビューが初期から表示されてほしい。
イメージ説明

↓画像②:左上の「<」押下時。メインコンテンツのビューが表示されるものの、サイドメニューと同じく細長い形で表示されてしまう。
イメージ説明

↓画像③:参考。左からスワイプしてのメニュー表示状態。(画像一部加工)
イメージ説明

該当のソースコード

SwiftUI

1import SwiftUI 2 3class EnvStatus: ObservableObject { 4 @Published var isTwinMenu: Bool = false 5} 6 7struct DragMainMenuView: View { 8 // offset変数でメニューを表示・非表示するためのオフセット 9 @State private var offset = CGFloat.zero 10 @State private var closeOffset = CGFloat.zero 11 @State private var openOffset = CGFloat.zero 12 13 //スライドメニュー1つあたりの幅の画面に対する比率 14 static let MENU_WIDTH_RECIO_SINGLE: Double = 0.4 15 16 //スライドメニュー1つあたりの幅の画面に対する比率- 17 @State var menuWidthRecio: Double = DragMainMenuView.MENU_WIDTH_RECIO_SINGLE 18 19 //他画面から受け取る情報 20 @ObservedObject var envStat_DragMainMenuView: EnvStatus = EnvStatus() 21 22 var body: some View { 23 // 画面サイズの取得にGeometoryReaderを利用 24 GeometryReader { geometry in 25 ZStack(alignment: .leading) { 26 27 NavigationView { 28 // メインコンテンツ 29 MainContentsView() 30 31 .background(Color.white) 32 .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center) 33 .navigationBarTitle("This is bar", displayMode: .inline) 34 .edgesIgnoringSafeArea(.vertical) 35 } 36 37 // スライドメニュー 38 SideMenuView().environmentObject(envStat_DragMainMenuView) 39 .background(Color.white) 40 .frame(width: geometry.size.width * CGFloat(self.menuWidthRecio)) 41 .edgesIgnoringSafeArea(.bottom) 42 // 最初に画面のオフセットの値をスライドメニュー分マイナス 43 .onAppear(perform: { 44 self.offset = geometry.size.width * -1 45 self.closeOffset = self.offset 46 self.openOffset = .zero 47 }) 48 .offset(x: self.offset) 49 // スライドのアニメーションを設定 50 .animation(.default) 51 } 52 // ジェスチャー 53 // スワイプのしきい値を設定してユーザの思わぬメニューの出現を防ぐ 54 .gesture(DragGesture(minimumDistance: 5) 55 .onChanged{ value in 56 // オフセットの値(メニューの位置)をスワイプした距離に応じて狭める 57 if (self.offset < self.openOffset) { 58 self.offset = self.closeOffset + value.translation.width 59 } 60 } 61 .onEnded { value in 62 // スワイプの終了位置が開始位置よりも右だったらメニューを開く 63 if (value.location.x > value.startLocation.x) { 64 self.offset = self.openOffset 65 } else { 66 self.offset = self.closeOffset 67 } 68 } 69 ) 70 } 71 //メニューが2本表示か1本表示かによってメニューの幅を変化させる 72 .onChange(of: self.envStat_DragMainMenuView.isTwinMenu, perform: { value in 73 if value { 74 menuWidthRecio = DragMainMenuView.MENU_WIDTH_RECIO_SINGLE * 2.0 75 } 76 else { 77 menuWidthRecio = DragMainMenuView.MENU_WIDTH_RECIO_SINGLE 78 } 79 }) 80 81 } 82} 83

試したこと

MainContentsViewやNavigationViewにframeモディファイアにて幅を画面いっぱいに設定してみましたが、表示幅は変わりませんでした。

補足情報(FW/ツールのバージョンなど)

Xcode:Ver.12.3
シミュレータiOS:14.3
Swift:Ver.5.3.2

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

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

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

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

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

guest

回答1

0

自己解決

NavigationViewについて、以下のように記述した時、原則として(画面が広い場合)

・View2は背面側に配置される
・View1は前面にサイドメニューとして表示される

という仕様ですが、

SwiftUI

1NavigationView { 2 View1() 3 View2() 4}

以下のようにViewをひとつだけ定義した場合は

・背面側にはなにもなし(NavigationBarのみ表示される)
・View1は前面にサイドメニューとして表示される

という動きになるようです。

SwiftUI

1NavigationView { 2 View1() 3}

今回は後者にあたるパターンであったため、
メインコンテンツ用のビューがサイドメニュー扱いで細長く表示されていた、
というだけのことでした。
おさがわせしました。

投稿2021/11/04 09:30

eleele28

総合スコア18

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問