2

I'm using some code from here to allow users to dismiss the keyboard when scrolling.

However when I include that functionality in the list, it leads swipe to delete to some strange behaviour, only working sometimes etc. Dragging to reorder items once in edit mode also doesn't work.

Is there a way to dismiss the keyboard upon scrolling, without losing that functionality? Preferably no "hacky" solutions


import SwiftUI

struct ContentView: View {

   @State var textfieldValue: String = ""
   @State var numbers: [String] = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"]

   var body: some View {
      NavigationView {

         VStack {

            TextField("Add item", text: self.$textfieldValue, onCommit: {
               print("Added")
            })
               .textFieldStyle(RoundedBorderTextFieldStyle())
               .padding()

            List {
               ForEach(numbers, id: \.self) { number in
                  Text(number)
               }.onDelete(perform: delete)
                  .onMove(perform: move)
            }.resignKeyboardOnDragGesture()   // ===== HERE =====

               .navigationBarItems(leading:
                  EditButton())            
         }
      }
   }

   func delete(at offsets: IndexSet) {
      numbers.remove(atOffsets: offsets)
   }

   func move(from source: IndexSet, to destination: Int) {
      numbers.move(fromOffsets: source, toOffset: destination)
   }

}



// This enables the scroll to dismiss functionality

extension UIApplication {
    func endEditing(_ force: Bool) {
        self.windows
            .filter{$0.isKeyWindow}
            .first?
            .endEditing(force)
    }
}

struct ResignKeyboardOnDragGesture: ViewModifier {
    var gesture = DragGesture().onChanged{_ in
        UIApplication.shared.endEditing(true)
    }
    func body(content: Content) -> some View {
        content.gesture(gesture)
    }
}

extension View {
    func resignKeyboardOnDragGesture() -> some View {
        return modifier(ResignKeyboardOnDragGesture())
    }
}



altec
  • 135
  • 1
  • 10

1 Answers1

0

Xcode 14 / iOS 16

Now dismiss on scroll works by-default (at least for code like in provided), but in the cases where it is not there is explicit modifier to activate it.

Like

List {
   ForEach(numbers, id: \.self) { number in
      Text(number)
   }.onDelete(perform: delete)
      .onMove(perform: move)
}
.scrollDismissesKeyboard(.immediately)    // << here !!

Note: by-default is .automatic mode used

Asperi
  • 228,894
  • 20
  • 464
  • 690