Fabio
Fabio

Reputation: 333

SwiftUI InputAccessoryView

I'm trying to build a chat view in SwiftUI and I want to append my input views to the keyboard, so that when I dismiss the keyboard by dragging my view gets moved with it.

When I was using UIKit I overwrote the inputAccessoryView of the ViewController. Is something similar possible with SwiftUI?

EDIT: I already saw that I can add a UIKit TextField and add a InputAccessory for this text field. However that's not what I want to do. I want to have a global inputAccessoryView in my SwiftUI View and add my custom input view as a subview, so that it is always Visible and not an addition to my TextField.

Upvotes: 3

Views: 882

Answers (1)

Mab.init
Mab.init

Reputation: 206

I see two possible solutions to the behavior you want.

  1. In some cases, SwiftUI views move out of the way of the keyboard automatically
  2. in iOS 15 and later you can create an InputAccessoryView in Swiftui

1: In swiftUI, there are several safe areas which views lay themselves inside of by default. One of these is the keyboard safe area. This areas takes up the full screen of the device when the keyboard is hidden but shrinks to the non keyboard area of the screen when the keyboard is displayed. So in the example code below, the text field should move above the keyboard when it appears and drop down when the keyboard disappears (this does not work on an iPad when the keyboard is in the smaller floating mode).

VStack {
    ScrollView {
        ForEach(0 ..< 50) { item in
            Text("Demo Text")
                .frame(maxWidth: .infinity)
        }
            
    }
    TextField("Enter Text", text: $messageText)
}

2: In iOS 15+, you can create a toolbar in the keyboard location. This essentially acts as an InputAccessoryView does in UIKit. The difference between this and method 1 is that a view in here will only appear when the keyboard is displayed. The one expiation to this is when a wired or wireless keyboard is attached to the iPhone or iPad, the toolbar view will still be displayed just at the bottom of the screen.

.toolbar {
    ToolbarItemGroup(placement: .keyboard) {
        Text("Apears at top of keyboard")
    }
}

So putting 1 and 2 together, here is an example that implements both. You can run it in Xcode to help understand how both methods behave

VStack {
    ScrollView {
        ForEach(0 ..< 50) { item in
            Text("Demo Text")
                .frame(maxWidth: .infinity)
        }
            
    }
    TextField("Enter Text", text: $messageText)
}
.toolbar {
    ToolbarItemGroup(placement: .keyboard) {
        Text("Apears at top of keyboard")
    }
}

Upvotes: 1

Related Questions