With iOS 26, Apple introduced a new position for the search bar. It can now appear either in the top toolbar or at the bottom, to the right of the TabView, as shown in the figure:


It’s easy to add, we just need to add a tab with the search role:
import SwiftUI
struct ContentView: View {
@State var nomi = ["superman", "batman", "wonderwoman"]
@State var searchText: String = ""
@State var searchPresented = false
var body: some View {
TabView() {
Tab("First", systemImage: "car") {
Text("In the first tab")
}
Tab("Second", systemImage: "bicycle") {
Text("In the second tab")
}
Tab(role: .search) {
NavigationStack {
List(searchResult(text: searchText), id: \.self) { nome in
NavigationLink(destination: EmptyView()) {
Text(nome)
}
}
}
}
}.searchable(text: $searchText)
}
func searchResult(text: String) -> [String] {
if text.count == 0 {
return nomi
}
return nomi.filter({
(nome: String) -> Bool in
return nome.lowercased().contains(text.lowercased())
})
}
}Note that the searchable modifier is attached to the TabView. The logic is the same as for a search bar in the navigation bar.
Also, I’d like to point out something: if you have a pre-selected tab, make sure it’s set to the search tab. Otherwise, you’ll run into an issue where you can’t insert text into the search field. I’m not sure whether this is a bug or not, but it can be quite frustrating.
A working example of this behavior is:
struct ContentView: View {
@State var nomi = ["superman", "batman", "wonderwoman"]
@State var searchText: String = ""
@State var searchPresented = false
var body: some View {
TabView(selection: .constant(2)) {
Tab("First", systemImage: "car", value: 0) {
Text("In the first tab")
}
Tab("Second", systemImage: "bicycle", value: 1) {
Text("In the second tab")
}
Tab(value: 2, role: .search) {
NavigationStack {
List(searchResult(text: searchText), id: \.self) { nome in
NavigationLink(destination: EmptyView()) {
Text(nome)
}
}
}
}
}.searchable(text: $searchText)
}
func searchResult(text: String) -> [String] {
if text.count == 0 {
return nomi
}
return nomi.filter({
(nome: String) -> Bool in
return nome.lowercased().contains(text.lowercased())
})