70 %

Stacking SwiftUI views with .overlay()


I was writing a SearchBar component in SwiftUI and I needed to combine a magnifying glass with the text input to mimic the Discord search bar:

discord search bar

We have multiple potential solutions for this case.

  1. Wrap a native component like UISearchBar and use it in Swift
  2. Use ZStack to layer views on top of each other
  3. Use .overlay() on our TextField to parent a magnifying glass icon.

Views have the ability to overlay child components on top of them with specific alignments that are relative to the parent view. This means we can use .overlay() and an alignment to show a magnifying glass at the end of the TextInput.

swift
struct SearchInput: View {
@State var search: String = ""
var body: some View {
TextField("Search", text: $search)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(width: 200, alignment: .center)
.overlay(
Image(systemName: "magnifyingglass")
.padding(15),
alignment: .trailing
)
}
}

ZStack is another possible solution to this particular issue. We chose to not go with it here because .overlay conveys a more direct parent/child relationship between our components whereas a ZStack is a set of siblings overlaid on each other. .overlay also lets us set alignment to the bounds of the parent view.

.overlay accepts alignments that correlate to positions as such:

topLeadingtoptopTrailing
leadingcentertrailing
bottomLeadingbottombottomTrailing