Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show Profile Icon next to Large Navigation Bar Title in SwiftUI?

I am developing an App that supports multiple Profiles. I really like the way Apple displays the Profile Icon next to the Large Navigation Bar Title in all their Apps. See the Screenshot below:

Screenshot Example

My Question is the following:

  • Is it possible to achieve this in SwiftUI? And if so, how?
  • If it's not possible in pure SwiftUI, how can I achieve it including UIKit Code?

Thanks for your help.

like image 408
christophriepe Avatar asked Dec 12 '25 22:12

christophriepe


1 Answers

I solved this by using SwiftUI-Introspect, to "Introspect underlying UIKit components from SwiftUI".

Here is an example of a view:

struct ContentView: View {

    @State private var lastHostingView: UIView!
    
    var body: some View {
        NavigationView {
            ScrollView {
                ForEach(1 ... 50, id: \.self) { index in
                    Text("Index: \(index)")
                }
                .frame(maxWidth: .infinity)
            }
            .navigationTitle("Large title")
            .introspectNavigationController { navController in
                let bar = navController.navigationBar
                let hosting = UIHostingController(rootView: BarContent())
                
                guard let hostingView = hosting.view else { return }
                // bar.addSubview(hostingView)                                          // <--- OPTION 1
                // bar.subviews.first(where: \.clipsToBounds)?.addSubview(hostingView)  // <--- OPTION 2
                hostingView.backgroundColor = .clear
                
                lastHostingView?.removeFromSuperview()
                lastHostingView = hostingView
                
                hostingView.translatesAutoresizingMaskIntoConstraints = false
                NSLayoutConstraint.activate([
                    hostingView.trailingAnchor.constraint(equalTo: bar.trailingAnchor),
                    hostingView.bottomAnchor.constraint(equalTo: bar.bottomAnchor, constant: -8)
                ])
            }
        }
    }
}

Bar content & profile picture views:

struct BarContent: View {
    var body: some View {
        Button {
            print("Profile tapped")
        } label: {
            ProfilePicture()
        }
    }
}

struct ProfilePicture: View {
    var body: some View {
        Circle()
            .fill(
                LinearGradient(
                    gradient: Gradient(colors: [.red, .blue]),
                    startPoint: .topLeading,
                    endPoint: .bottomTrailing
                )
            )
            .frame(width: 40, height: 40)
            .padding(.horizontal)
    }
}

The .frame(width: 40, height: 40) & hostingView.bottomAnchor constant will need to be adjusted to your needs.

And the results for each option (commented in the code):

Option 1 Option 2
View sticks when scrolled View disappearing underneath on scroll
Result - Option 1 Result - Option 2
like image 94
George Avatar answered Dec 14 '25 13:12

George