UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

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.

3      

@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

3      

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.

3      

Setting the global AccentColor in Assets.xcassets as descirbed in

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

3      

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)

4      

The easy way?

I used .accentColor(myColor) on the NavigationLink and it worked well on the iPad!

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.