[macOS] How to remove List scroll indicators when listStyle is SidebarListStyle?

I create a macOS SwiftUI project, and I want to use Sidebar.

So I saw Paul Hudson's video, he adds .listStyle(SidebarListStyle()) on List.


Here is a screenshot form Paul's video, it works correctly.


I write my own code, set listStyle is SidebarListStyle, but List has scroll indicators (both horizontal and vertical).


This is my code:


import SwiftUI

struct HomeView: View {
    private let lists = ["Link 1", "Link 2", "Link 3"]

    var body: some View {
        NavigationView {
            List {
                ForEach(lists, id: \.self) {
                    list in
                    NavigationLink(destination:
                        Text("Hello, World!")
                            .frame(maxWidth: .infinity, maxHeight: .infinity)) {
                        Text(list)
                    }
                }
            }
            .listStyle(SidebarListStyle())
            .frame(minWidth: 200)
        }
    }
}


I found a StackOverflow question [Is there a way to hide scroll indicators in a SwiftUI List?], but the accepted answer reset all UITableView appearance, this is not what I wanted.

This is like a bug. There is no problem with my macbook. I have this problem with my external monitor. It should be reported to apple.

There is no way to do that by using pure SwiftUI. But we can access NSScrollView to make magical:
  1. Create NSViewAccessor => helping access NSView of a SwiftUI View

Code Block
extension View {
  func onNSView(added: @escaping (NSView) -> Void) -> some View {
    NSViewAccessor(onNSViewAdded: added) { self }
  }
}
struct NSViewAccessor<Content>: NSViewRepresentable where Content: View {
  var onNSView: (NSView) -> Void
  var viewBuilder: () -> Content
   
  init(onNSViewAdded: @escaping (NSView) -> Void, @ViewBuilder viewBuilder: @escaping () -> Content) {
    self.onNSView = onNSViewAdded
    self.viewBuilder = viewBuilder
  }
   
  func makeNSView(context: Context) -> NSViewAccessorHosting<Content> {
    return NSViewAccessorHosting(onNSView: onNSView, rootView: self.viewBuilder())
  }
   
  func updateNSView(_ nsView: NSViewAccessorHosting<Content>, context: Context) {
    nsView.rootView = self.viewBuilder()
  }
}
class NSViewAccessorHosting<Content>: NSHostingView<Content> where Content : View {
  var onNSView: ((NSView) -> Void)
   
  init(onNSView: @escaping (NSView) -> Void, rootView: Content) {
    self.onNSView = onNSView
    super.init(rootView: rootView)
  }
   
  @objc required dynamic init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
   
  required init(rootView: Content) {
    fatalError("init(rootView:) has not been implemented")
  }
   
  override func didAddSubview(_ subview: NSView) {
    super.didAddSubview(subview)
    onNSView(subview)
  }
}


2. Hide scroller of NSScrollView
Code Block swift
List{
...
  }.onNSView(added: {nsview in
    let root = nsview.subviews[0] as! NSScrollView
    root.hasVerticalScroller = false
    root.hasHorizontalScroller = false
  })

[macOS] How to remove List scroll indicators when listStyle is SidebarListStyle?
 
 
Q