NEW: Start my new Ultimate Portfolio App course with a free Hacking with Swift+ trial! >>

How to change background color of selected NavigationLink in List?

Forums > SwiftUI

Hello, hope you doing fantastic.

I got master-detail view app where UI is build with SwiftUI.

Master view is a List of NavigationLink's. Data for each NavigationLink is populated via Core Data fetch request.

import CoreData
import SwiftUI

struct FilteredList: View {
    var fetchRequest: FetchRequest<Book>
    var books: FetchedResults<Book> {
        fetchRequest.wrappedValue
    }
    @Environment(\.managedObjectContext) var moc

    var body: some View {
        List {
            ForEach(books, id: \.self) { book in
                NavigationLink(destination: BookDetailView(book: book)) {
                    HStack {
                        Text(book ?? "Book Default Title")
                    }
                }
            }
        }
    }
}

What I am trying to achieve in Mac Catalyst version of the app: I need to change background of currently selected NavigationLink in List to say, for example, system green color. Because in ligh mode on the Mac list row has black text and default blue background, so the content is hard to read. Please, see the screenshot:

I tried to set @State private var selectedBook: Book? and add

.onTapGesture {
    self.selectedBook = book
    print("Debug: tap")
}

to NavigationLink, and then change background for NavigationLink this way:

.listRowBackground(self.selectedBook == book ? Color.green : Color.clear)

But print statement work less than half of the time, I don't think this is a right way.

How can I change background color of selected item in List? Any help is much appreciated. Thanks.

   

@a7ex  

In order to monitor the selection of a list of NavigationLinks you may want to try something like:

@State private var selectedBook: String?

...

    NavigationLink(
        destination: BookDetailView(book: book),
        tag: book.id,
        selection: self.$selectedBook) {
            HStack {
                Text(book ?? "Book Default Title")
            }
    }

...

Hope that helps alex

   

Honestly, I would come up with some other solution. The selection highlight color is determined by the user's choice in System Preferences > General. If you are going to ignore the user's preference, you'd better have a damn good reason to do so or risk annoying your users. Personally, if an app did that to me, I'd probably not use it unless I absolutely had to.

   

Setting the global AccentColor in Assets.xcassets as descirbed in

https://developer.apple.com/documentation/watchkit/setting_the_app_s_tint_color

   

Thanks @a7ex your suggestion helped me solve a similar issue where an iPad in landscapel mode was using the .tintcolor to highlight list items and it was really ugly so I used your suggestion to track which navlink was selected and then used the following to make things look right.

.listRowBackground(self.selectedItem == item ? Color.secondary : Color.clear)

   

Hacking with Swift is sponsored by RevenueCat

SPONSORED Building and maintaining in-app subscription infrastructure is hard. Luckily there's a better way. With RevenueCat, you can implement subscriptions for your app in hours, not months, so you can get back to building your app.

Try it for free

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.