Spatial SwiftUI: Window Ornaments
Ornaments allow us to decorate our windows with information and controls that may not fit in the main window region.
Overview
We can add a simple ornament to our windows like so.
{...} // root view
.ornament(attachmentAnchor: .scene(.topLeading)) {
Text("Ornament")
.padding(20)
.cornerRadius(20)
}This will create a text view that is anchored to the top leading area of the window. Anchors in this context refer to UnitPoint values. We can use one of the pre-built properties (.top, .center .leading, etc.). We can also specify an X and Y value if we need a custom position.
We can control ornament visibility if we need to show and hide these. This will only show when ourState is true.
{...} // root view
.ornament(visibility: ourState, attachmentAnchor: .scene(.topLeading)) {
Text("Ornament")
.padding(20)
.cornerRadius(20)
}We can set the alignment of the view on the anchor as well.
{...} // root view
.ornament(visibility: ourState, attachmentAnchor: .scene(ourAnchor), contentAlignment: ourAlignment) {
Text("Ornament")
.padding(20)
.cornerRadius(20)
}Later–in the labs–we will combine ornament with rotation and transforms to create more advanced layouts.
Video Demo
Full Example Code
Please excuse my repetitive code…
struct Example037: View {
@State var ornamentVisibility: Visibility = .hidden
@State var ornamentAnchor: UnitPoint = .top
@State var ornamentAlignment: Alignment = .center
// convenience functions so I don't have to repeat "withAnimation" in every button
func setAnchor(_ newAnchor: UnitPoint) {
withAnimation {
ornamentAnchor = newAnchor
}
}
func setAlignment(_ newAlignment: Alignment) {
withAnimation {
ornamentAlignment = newAlignment
}
}
var body: some View {
ZStack {
VStack(spacing: 20) {
Button{
withAnimation {
ornamentVisibility = ornamentVisibility == .visible ? .hidden : .visible
}
} label: {
Text("Toggle Ornament")
}
Spacer()
HStack(spacing: 40) {
// Anchor buttons
VStack {
Text("Anchor")
HStack(alignment: .center) {
Button{
setAnchor(.topLeading)
} label: {
Image(systemName: "arrow.up.left")
}
Button{
setAnchor(.top)
} label: {
Image(systemName: "arrow.up")
}
Button{
setAnchor(.topTrailing)
} label: {
Image(systemName: "arrow.up.right")
}
}
HStack(alignment: .center) {
Button{
setAnchor(.leading)
} label: {
Image(systemName: "arrow.left")
}
Button{
setAnchor(.center)
} label: {
Image(systemName: "square")
}
Button{
setAnchor(.trailing)
} label: {
Image(systemName: "arrow.right")
}
}
HStack(alignment: .center) {
Button{
setAnchor(.bottomLeading)
} label: {
Image(systemName: "arrow.down.left")
}
Button{
setAnchor(.bottom)
} label: {
Image(systemName: "arrow.down")
}
Button{
setAnchor(.bottomTrailing)
} label: {
Image(systemName: "arrow.down.right")
}
}
}
// Alignment buttons
VStack {
Text("Alignment")
HStack(alignment: .center) {
Button{
setAlignment(.topLeading)
} label: {
Image(systemName: "arrow.up.left")
}
Button{
setAlignment(.top)
} label: {
Image(systemName: "arrow.up")
}
Button{
setAlignment(.topTrailing)
} label: {
Image(systemName: "arrow.up.right")
}
}
HStack(alignment: .center) {
Button{
setAlignment(.leading)
} label: {
Image(systemName: "arrow.left")
}
Button{
setAlignment(.center)
} label: {
Image(systemName: "square")
}
Button{
setAlignment(.trailing)
} label: {
Image(systemName: "arrow.right")
}
}
HStack(alignment: .center) {
Button{
setAlignment(.bottomLeading)
} label: {
Image(systemName: "arrow.down.left")
}
Button{
setAlignment(.bottom)
} label: {
Image(systemName: "arrow.down")
}
Button{
setAlignment(.bottomTrailing)
} label: {
Image(systemName: "arrow.down.right")
}
}
}
}
}
.padding(100)
.ornament(
visibility: ornamentVisibility,
attachmentAnchor: .scene(ornamentAnchor),
contentAlignment: ornamentAlignment
) {
Text("Ornament")
.padding(20)
.background(.stepBlue)
.cornerRadius(20)
}
}
}
}Support our work so we can continue to bring you new examples and articles.
Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Follow Step Into Vision