删除/更改列表突出显示颜色(或调整项目之间的间隔)

时间:2020-06-28 12:28:59

标签: macos swiftui

我目前正在为 MacOS -应用程序的SwiftUI列表制作自定义行模板。由于我找不到删除/调整蓝色突出显示颜色的方法(我只找到了适用于iOS的解决方案),因此我制作了以下模板,该模板涵盖了蓝色部分,但在所需区域内“模仿”了它,看起来像这:Screenshot。我通过使用负填充等方法覆盖了大多数突出显示颜色。但是,我只是无法消除项目顶部的一些蓝色像素(在屏幕截图中标记)。

我的代码如下:

行模板(简化版)

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(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)

问题

是否有办法覆盖其余的突出显示颜色,或者甚至更好地完全消除突出显示颜色?不幸的是,进一步调整填充似乎并没有帮助...(但也许我错过了什么)

非常感谢。

更新

选择绑定如下所示(如果相关的话:

    class UserDataViewModel: ObservableObject {

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

1 个答案:

答案 0 :(得分:2)

我会建议更改方向...如果您不希望使用默认选择(要与之抗争的亮点),那么就不要使用它,而只需点按它,就像下面的示例一样(由于提供了此示例)快照不可测试)

通过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())
            }
        }
    }
}

替代::这里可能是基于NSTableView(在macOS上List之下)通知的替代

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
    }
}