Search code examples
swiftswiftuigesturemodal-view

Why .gesture() in SwiftUI can not be used on my entire modal view?


I have this really simple LostPasswordView using SwiftUI. This form is being presented as a modal view. I use a .onTapGesture and a DragGesture() to dismiss the keyboard.

The issue is that only the little part of the view around the TextField responds to these gestures. Which does not improve the user experience as it is confusing on where these actions work.

Why can I not use the gesture on all the SwiftUI modal View? I was thinking that it might be because there is already a swipe down gesture to dismiss the modal view...

import SwiftUI

//MARK: Lost password view presented as a modal
struct LostPasswordView: View {

  @State var email = ""

  var body: some View {
    //MARK: User entry
    VStack {
      ///email
      UserEntryTextField(title: TextFieldName.email.rawValue,
                         userEntry: email
      )
        .padding(.top, 198)

      Spacer()

      //MARK: Modify password button
      MainButton(action: {},
                 title: .modifyPassword)
    }
    .padding(.bottom)
    .onTapGesture {
      self.dismissKeyboard()
    }.simultaneousGesture(
      DragGesture().onChanged({ (_) in
        self.dismissKeyboard()
      }))
  }
}

//MARK: Dismiss keyboard
extension LostPasswordView {
  func dismissKeyboard() {
    UIApplication.shared.dismissKeyboard()
  }
}

Solution

  • Specify .frame modifier for your VStack as follows (and probably you need some background, because transparent containers do not track events)

    VStack {
    ...
    }
    .background(Color.white)
    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)