Remove/Change list highlight-color (or adjust space between items)

佐手、 提交于 2021-02-08 03:26:11

问题


I am currently making a custom row template for a SwiftUI-list for a MacOS-application. Since i didn't find a way remove/adjust the blue highlight-color (I only found solutions for iOS), I made the the following template which covers the blue-part but "mimics" it within the desired area, which looks like this: Screenshot. I managed to cover most of the highlight-color by using negative paddings, etc.; however, I just can't get rid of some blue pixels on the top of the item (marked in screenshot).

My code looks like this:

Row template (simplified version)

struct EntryRow: View {
    var body: some View {
        
        // Outer frame (white space with shadow)
        ZStack(alignment: .topLeading) {
            
            // Inner frame (actual content)
            ZStack(alignment: .topLeading) {

                            .frame(minWidth: 0, maxWidth: .infinity)
            .frame(minHeight: 0, maxHeight: .infinity)
            .padding(.vertical, 0)
            .background(self.model.selectedEntries.firstIndex(of: entry.id) != nil ? Color.blue : Color(NSColor.controlBackgroundColor))
 // 👆🏻 Changes color according to selection state of row
            .overlay(
                RoundedRectangle(cornerRadius: 4)
                    .stroke(Color.black, lineWidth: 0)
            )
                .clipShape(RoundedRectangle(cornerRadius: 4))
            
            
        }.padding(15)
            .background(Color(NSColor.controlBackgroundColor))
 // 👆🏻 Changes background color so that it corresponds to the list's background color (which achieves the white space between the items)
            .shadow(color: Color(NSColor.tertiaryLabelColor), radius: 2)
        
    }    
}

List

The rows are loaded as follows:

List(selection: self.$model.selectedEntries) {
                    ForEach(self.model.entries, id: \.id) { item in
                        EntryRow(entry: item)
                            .padding(-15)
                    }
                }
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .padding(.top, -13).padding(.horizontal, -4)

Question

Is there a way to cover the remaining highlight color, or - even better - to remove the highlight color entirely? Unfortunately, adjusting the paddings further doesn't seem to help... (but maybe I'm missing something)

Thanks a lot in advance.

Update

The selection binding looks as follows (in case that is relevant:

    class UserDataViewModel: ObservableObject {

    @Published var entries = [Entry]()
    
    @Published var selectedEntries: Set<Int32> = Set<Int32>() {
        didSet {
            print(selectedEntries.count)
        }
    }

回答1:


I would propose the change a direction... If you don't want default selection (the highlight you fight with) then just don't use it and make it just on tap, like in below example (due to provided snapshot is not testable)

Tested with Xcode 11.4

struct PersonList: View {
    @State var selectedPerson: String?

    let persons = ["Person 1", "Person 2", "Person 3"]

    var body: some View {
        VStack {
            Text("Selected: \(selectedPerson ?? "<none>")")
            List {
                 ForEach(persons, id: \.self) { person in
                    VStack {
                        Text(person)
                    }.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                    .background(Color(NSColor.controlBackgroundColor))
                    .onTapGesture {
                        self.selectedPerson = person
                    }
                 }
                 .listRowInsets(EdgeInsets())
            }
        }
    }
}

Alternate: here is possible alternate based on NSTableView (which is underneath of List on macOS) notifications

List(selection: self.$model.selectedEntries) {
    ForEach(self.model.entries, id: \.id) { item in
        EntryRow(entry: item)
    }
}
.onReceive(NotificationCenter.default.publisher(for: NSTableView.selectionIsChangingNotification)) { notification in
    if let tableView = notification.object as? NSTableView {
        tableView.selectionHighlightStyle = .none
    }
}


来源:https://stackoverflow.com/questions/62622560/remove-change-list-highlight-color-or-adjust-space-between-items

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!