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

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

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

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

0回答

1096閲覧

特定のコードが影響し、リストの削除機能が動作しなくなる

ogasawas216

総合スコア0

iOS

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2021/02/19 17:07

編集2021/03/23 16:50

前提・実現したいこと

SwitfUIで以下の機能を実装すること。

  1. リストのアイテム削除機能
  2. 右スワイプによる左メニューの表示機能
  3. 左メニュー表示時、背景をグレーアウトする機能

上記の2・3の機能を実装中に以下の問題が発生しました。
解決策ご存知の方いらっしゃいましたら、ご教示のほどよろしくお願いいたします。

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

エラーメッセージ: 無し

以下の該当のソースコード以下のコードをアンコメントすると、リストの削除機能が動作しない。直下のコード(2箇所)が影響し、ListのonDeleteが正常に動作しない。
それぞれのコードは単体では動作します。コメントアウトされたコードのどちらかをアンコメントするとListが動作しなくなります。

該当のソースコード

swift

1import SwiftUI 2import RealmSwift 3 4struct ContentView: View { 5 // メモ 6 @ObservedObject var memos = ContentViewModel() 7 // モーダル表示フラグ 8 @State private var isShow = false 9 // メニューを表示/非表示する為のオフセットを保持 10 @State private var offset = CGFloat.zero 11 @State private var closeOffset = CGFloat.zero 12 @State private var openOffset = CGFloat.zero 13 14 var body: some View { 15 GeometryReader { geometry in 16 ZStack(alignment: .leading) { 17 VStack { 18 ZStack { 19 HStack { 20 Button(action: { 21 self.offset = self.openOffset 22 }){ 23 Image(systemName: "list.bullet") 24 .foregroundColor(.black) 25 } 26 Spacer() 27 } 28 Text("Memo") 29 } 30 .padding(.horizontal) 31 32 Divider() 33 List { 34 ForEach(memos.models, id: .id) { models in 35 Text("(models.content)") 36 } 37 .onDelete(perform: { indexSet in 38 let realm = try! Realm() 39 try! realm.write() { 40 realm.delete(self.memos.models[indexSet.first!]) 41 } 42 }) 43 } 44 } 45 .background(Color.white) 46 .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center) 47 // 以下のコードをアンコメントすると、リストの削除機能が動作しない。 48 // 左メニューが出てきたらメインコンテンツをグレイアウトする 49 // Color.gray.opacity( 50 // Double((self.closeOffset - self.offset)/self.closeOffset) - 0.4 51 // ) 52 53 // 左メニュー 54 LeftMenuView() 55 .background(Color.white) 56 .frame(width: geometry.size.width * 0.7) 57 // 最初に画面のオフセットの値を左メニュー分マイナスする 58 .onAppear(perform: { 59 self.offset = geometry.size.width * -1 60 self.closeOffset = self.offset 61 self.openOffset = .zero 62 }) 63 .offset(x: self.offset) 64 // スライドのアニメーションを設定します 65 .animation(.default) 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 // } else { 81 // self.offset = self.closeOffset 82 // } 83 // } 84 // ) 85 86 VStack { 87 Spacer() 88 HStack { 89 Spacer() 90 // メモ作成ボタン 91 Button(action: { 92 isShow = true 93 }, label: { 94 Image(systemName: "pencil") 95 .resizable() 96 .frame(width: 20, height: 20) 97 .foregroundColor(.black) 98 .padding(.all,20) 99 }) 100 .sheet(isPresented: $isShow) { 101 ModalView(content: "", isActive: $isShow ) 102 } 103 } 104 } 105 } 106 } 107} 108 109struct ModalView: View { 110 @Environment(.presentationMode) var presentation 111 @State var content: String 112 @Binding var isActive: Bool 113 114 var body: some View { 115 VStack(spacing: 16) { 116 TextField("メモを入力してください", text: $content) 117 .textFieldStyle(RoundedBorderTextFieldStyle()) 118 Button("保存") { 119 let memo = Memo() 120 memo.content = content 121 122 let realm = try! Realm() 123 try! realm.write() { 124 realm.add(memo) 125 } 126 presentation.wrappedValue.dismiss() 127 } 128 Button("閉じる") { 129 isActive = false 130 } 131 } 132 .padding() 133 } 134} 135 136class ContentViewModel: ObservableObject { 137 private var token: NotificationToken? 138 private var results = try? Realm().objects(Memo.self) 139 @Published var models: [Memo] = [] 140 141 init() { 142 token = results?.observe { [weak self] _ in 143 self?.models = self?.results?.map { $0 } ?? [] 144 } 145 } 146 147 deinit { 148 token?.invalidate() 149 } 150}

試したこと

  • 問題のコードをコメントアウト/アンコメントし、リストの削除機能へ影響していることの確認
  • 環境変数editModeの設定やEditButton()による編集可能状態への変更で削除可能か(=>削除できない)

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

  • Xcode Version 12.4 (12D4e)
  • Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)

Target: x86_64-apple-darwin19.6.0

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

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

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

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

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

hoshi-takanori

2021/02/20 00:50

メインコンテンツをグレイアウトするための Color.gray に関しては、これが存在するとタッチイベントが下のビューに届かないので、表示の切り替えを opacity ではなく if にすれば良いと思います。 DragGesture に関しては、List の削除やスクロールとかち合うのは当然だと思いますが…。
ogasawas216

2021/02/21 15:27

返信ありがとうございます。 メインコンテンツをグレイアウトする処理については ご提案いただいた内容で修正してみます。 DragGestureに関しては理解が浅い為、 もう少し調べてから再度使用したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問