如何从 Mac OS 中的 SwiftUI 列表中删除底部/顶部项目填充

Posted

技术标签:

【中文标题】如何从 Mac OS 中的 SwiftUI 列表中删除底部/顶部项目填充【英文标题】:How to remove bottom/top item padding from SwiftUI List in Mac OS 【发布时间】:2020-08-01 11:21:16 【问题描述】:

我很难使用 SwiftUI 从 MacOS 中的单元格中删除所有填充。即使在Apple的代码中我似乎也无法做到!

https://developer.apple.com/tutorials/swiftui/creating-a-macos-app

例如,在 Xcode 中 MacLandmarks 文件夹的 LandMarkList 中,我在 forEach 的末尾放了一个 .listRowInsets(EdgeInsets()),这样代码看起来像这样:

struct LandmarkList: View 
    @EnvironmentObject private var userData: UserData
    @Binding var selectedLandmark: Landmark?
    @Binding var filter: FilterType

    var body: some View 
        List(selection: $selectedLandmark) 
            ForEach(userData.landmarks)  landmark in
                if (!self.userData.showFavoritesOnly || landmark.isFavorite)
                    && (self.filter == .all
                        || self.filter.category == landmark.category
                        || (self.filter.category == .featured && landmark.isFeatured)) 
                    LandmarkRow(landmark: landmark).tag(landmark)
                        .background(Color.red)
                
            
            .listRowInsets(EdgeInsets())
        
    

我还在每个单元格中设置了红色背景色。这是我得到的结果:

关键是我似乎无法摆脱此列表单元格之间的垂直空间。我见过的所有解决方案似乎都为此提到了 ios,但我想在 Mac OS 中执行此操作(应该具有相同的行为,但事实并非如此)。

【问题讨论】:

【参考方案1】:

这是可能解决方案的演示(使用 Xcode 11.4 / macOS 10.15.6 测试)。

注意:如果需要有多个活动列表(即 NSTableView)并且其中一些应该具有单元间间距(也称为分隔符),那么它们应该由 SwiftUI 工具完成,因为这种方法会禁用单元间间距对于所有可见列表

var body: some View 
    VStack 
        Text("Selected: \(selectedPerson ?? "<none>")")
        List(selection: $selectedPerson) 
             ForEach(persons, id: \.self)  person in
                Text(person)
             
             .listRowBackground(Color.red)
             .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
        .border(Color.green)
        .onReceive(NotificationCenter.default.publisher(for: NSView.frameDidChangeNotification)) 
            guard let tableView = $0.object as? NSTableView else  return 
            tableView.intercellSpacing = .zero
        
    

【讨论】:

还有什么办法可以去掉分隔符吗? 我尝试了您的解决方案。我发现了两件事: 1. listRowInsets 完全没有做任何事情。 2.没有分隔符!我运行该应用程序并单击 Xcode 的 View Debugger。单元格之间没有分隔符,只有填充! 这行得通,但让我提出 3 点观察: 1. Apple 的 listRowsInsets 有问题,不能在 macOS 上运行? 2. 这是唯一的方法,但效率低下(应用程序内每个视图的每个帧更新都会调用通知!)。 3. 最好只使用 NSTableView 并将其包裹在 SwiftUI 视图中,对吗?我正在尝试显示数十万个项目的列表。

以上是关于如何从 Mac OS 中的 SwiftUI 列表中删除底部/顶部项目填充的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SwiftUI 中的列表中获取屏幕行?

如何从 SwiftUI 和 Realm 中另一个列表中的对象中添加和删除列表中的对象

SwiftUI Mac OS DatePicker 在编辑时跳回到今天

如何从firestore中检索swiftUI中的预定义项目列表?

SwiftUI:从列表中的项目获取切换状态

如何从 WatchOS 的 SwiftUI 列表中删除分隔符?