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

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回答

1953閲覧

スワイプでせり出してくるサイドメニューの動作が重い

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/07 02:50

前提・実現したいこと

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

発生している問題

スライドメニューについてスワイプで出るには出るのですが、
動作が重く引っかかる場合が多いです。
スワイプ判定がされない場合もしばしばあります。

具体的な解決策自体もそうですが、「どういう方法でアプローチしてデバッグしたらよいか」
をご教示いただけるとありがたいです。

該当のソースコード

Swift

1import SwiftUI 2import Combine 3 4class EnvStatus: ObservableObject { 5 //子から親 6 //2段メニュー有効 7 @Published var isTwinMenu: Bool = false 8} 9 10struct DragMainMenuView: View { 11 // offset変数でメニューを表示・非表示するためのオフセットを保持します 12 @State private var offset = CGFloat.zero 13 @State private var closeOffset = CGFloat.zero 14 @State private var openOffset = CGFloat.zero 15 16 //スライドメニュー1つあたりの幅の画面に対する比率 17 static let MENU_WIDTH_RECIO_SINGLE: Double = 0.4 18 19 //スライドメニュー1つあたりの幅の画面に対する比率- 20 @State var menuWidthRecio: Double = DragMainMenuView.MENU_WIDTH_RECIO_SINGLE 21 22 //他画面とやりとりする情報 23 @ObservedObject var envStat_DragMainMenuView: EnvStatus = EnvStatus() 24 var requester = PassthroughSubject<Bool, Never>() 25 26 var body: some View { 27 // 画面サイズの取得にGeometoryReaderを利用します 28 GeometryReader { geometry in 29 30 ZStack(alignment: .leading) { 31 32 NavigationView { 33 34 ZStack(alignment: .leading) { 35 // メインコンテンツ 36 MainContents() 37 38 .background(Color.white) 39 .navigationBarTitle("This is bar", displayMode: .inline) 40 .edgesIgnoringSafeArea(.vertical) 41 42 // スライドメニューがでてきたらメインコンテンツをグレイアウトします 43 Color.gray.opacity( 44 Double((self.closeOffset - self.offset)/self.closeOffset) - 0.4 45 ) 46 47 // スライドメニュー 48 MenuView(reqPublisher: requester.eraseToAnyPublisher()).environmentObject(envStat_DragMainMenuView) 49 .background(Color.white) 50 .frame(width: geometry.size.width * CGFloat(self.menuWidthRecio)) 51 .edgesIgnoringSafeArea(.bottom) 52 // 最初に画面のオフセットの値をスライドメニュー分マイナスします。 53 .onAppear(perform: { 54 self.offset = geometry.size.width * -1 55 self.closeOffset = self.offset 56 self.openOffset = .zero 57 }) 58 .offset(x: self.offset) 59 // スライドのアニメーションを設定します 60 .animation(.default) 61 } 62 63 .edgesIgnoringSafeArea(.vertical) 64 } 65 .navigationViewStyle(StackNavigationViewStyle()) 66 } 67 // ジェスチャーに関する実装をします 68 // スワイプのしきい値を設定してユーザの思わぬメニューの出現を防ぎます 69 .gesture(DragGesture(minimumDistance: 5) 70 .onChanged{ value in 71 // オフセットの値(メニューの位置)をスワイプした距離に応じて狭めていきます 72 if (self.offset < self.openOffset) { 73 self.offset = self.closeOffset + value.translation.width 74 } 75 } 76 .onEnded { value in 77 // スワイプの終了位置が開始位置よりも右だったらメニューを開く 78 if (value.location.x > value.startLocation.x) { 79 self.offset = self.openOffset 80 81 //メニュー展開イベントを発行する 82 self.requester.send(true) 83 } 84 //そうでないときはメニューを閉じる 85 else 86 { 87 self.offset = self.closeOffset 88 89 //メニュー格納イベントを発行する 90 self.requester.send(false) 91 } 92 } 93 ) 94 } 95 //メニューが2本表示か1本表示かによって幅を変化させる 96 .onChange(of: self.envStat_DragMainMenuView.isTwinMenu, perform: { value in 97 if value { 98 menuWidthRecio = DragMainMenuView.MENU_WIDTH_RECIO_SINGLE * 2.0 99 } 100 else { 101 menuWidthRecio = DragMainMenuView.MENU_WIDTH_RECIO_SINGLE 102 } 103 }) 104 105 } 106} 107 108struct MenuView: View { 109 @ObservedObject var envStat_DragMainMenuView: EnvStatus = EnvStatus() 110 var body: some View { 111 VStack(alignment: .leading) { 112 Image("animal_kuma") 113 .resizable() 114 .overlay( 115 Circle().stroke(Color.gray, lineWidth: 1)) 116 .frame(width: 60, height: 60) 117 .clipShape(Circle()) 118 Text("SwiftUIへの道") 119 .font(.largeTitle) 120 Text("@road2swiftui") 121 .font(.caption) 122 Divider() 123 ScrollView (.vertical, showsIndicators: true) { 124 HStack { 125 Image(systemName: "person") 126 Text("Profile") 127 } 128 HStack { 129 Image(systemName: "list.dash") 130 Text("Lists") 131 } 132 HStack { 133 Image(systemName: "text.bubble") 134 Text("Topics") 135 } 136 } 137 Divider() 138 Text("Settings and privacy") 139 } 140 .padding(.horizontal, 20) 141 } 142} 143 144struct DragMainMenuView_Previews: PreviewProvider { 145 static var previews: some View { 146 DragMainMenuView() 147 } 148} 149

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

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

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

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

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

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

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

hoshi-takanori

2021/11/07 07:45

動作が重いと言うか、スワイプが完了してからメニューを出してるために違和感があるような…。
guest

回答1

0

自己解決

NavigationViewと組み合わせるのをやめてelseif節にてViewを切り替えるように変更してみた結果、動作が軽くなりました。
NavigationViewとは相性が悪いのかもしれません。

投稿2021/11/10 07:22

eleele28

総合スコア18

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問