'SwiftUI Toolbar item getting clipped when back button is pressed

I've run in to a strange behavior in SwiftUI that I can't seem to work around.

Given the following simple example app I experience this behavior: The toolbar item renders correctly on the initial run, but navigating away and returning it gets clipped.

enter image description here

Sample code to recreate this:

ContentView.swift

import SwiftUI

struct ContentView: View {
    var body: some View {
      NavigationView {
        
        NavigationLink(destination: View2()) {
          Text("Hello, world!")
            .padding()
            .navigationTitle("View 1")
            .toolbar {
              Circle()
                .fill(Color.red)
                .frame(width: 150, height: 150, alignment: .center)
            }
        }
      }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

View2.swift

import SwiftUI

struct View2: View {
    var body: some View {
        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
    }
}

struct View2_Previews: PreviewProvider {
    static var previews: some View {
        View2()
    }
}



Solution 1:[1]

It is clipped by navigation bar as seen on view debug below so it is just rendering issue (should be clipped always):

demo1

A possible solution is to use that widget (Circle in the case) above NavigationView and align it with toolbar item.

demo

Here is main part:

.toolbar {
    Color.clear
        .frame(width: 150)
        .overlay(GeometryReader {
            Color.clear.preference(key: ViewPointKey.self,
                                 value: [$0.frame(in: .global).center])
        })
}

//...

Circle().fill(Color.red)
    .frame(width: 150, height: 150)
    .position(x: pos.x, y: pos.y)     // << here !!

//...

.onPreferenceChange(ViewPointKey.self) {
    pos = $0.first ?? .zero
}

Complete findings and code is here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Asperi