Find and replace in iOS and iPadOS 16
Apple introduced a redesigned find and replace experience in iOS and iPadOS 16. In SwiftUI this functionality is automatically supported by TextEditor view.
We also have some new APIs to customize find and replace in our apps.
# Disable replace
We can disable support for replace functionality by applying replaceDisabled() modifier to TextEditor
.
struct TextView: View {
@State private var text = ""
var body: some View {
TextEditor(text: $text)
.replaceDisabled()
}
}
# Disable find and replace
If we want to entirely disable the feature, we can use findDisabled() modifier. It will disable both find and replace and user won't be able to summon the system find UI when interacting with our TextEditor
.
struct TextView: View {
@State private var text = ""
var body: some View {
TextEditor(text: $text)
.findDisabled()
}
}
# Programmatically present system find UI
To programmatically summon the find interface, we can use findNavigator(isPresented:) modifier and pass it a binding to a Boolean value.
struct TextView: View {
@State private var text = ""
@State private var showFindUI = false
var body: some View {
TextEditor(text: $text)
.findNavigator(isPresented: $showFindUI)
.toolbar {
Toggle(isOn: $showFindUI) {
Label(
"Find",
systemImage: "magnifyingglass"
)
}
}
}
}
Note that if we want to disable replace inside the find UI that is presented programmatically, we have to make sure that replaceDisabled()
is placed closer to TextEditor
than findNavigator(isPresented:)
.
TextEditor(text: $text)
.replaceDisabled()
.findNavigator(isPresented: $showFindUI)
If we use findDisabled()
in conjunction with findNavigator(isPresented:)
, setting isPresented
binding of the find navigator to true
won't do anything, because findDisabled()
completely disables the feature.
Find and replace is only supported inside TextEditor
at the moment, TextField
doesn't have this functionality.
You can find a sample project for this post on GitHub.