删除 SwiftUI Mac 应用程序列表中右键单击行的轮廓

发布于 2025-01-09 01:06:33 字数 1659 浏览 2 评论 0原文

我正在使用 SwiftUI 构建 macOS 应用程序,并且在右键单击 List 项目时尝试删除(甚至掩盖)添加到该项目的边框。

默认情况下是这样的:

List Row

现在,右键单击并使用 contextMenu 视图修饰符:

List Row Right Click

我认为这是一个 NSTableView 怪癖,所以我尝试了这三篇 Stack Overflow 帖子中的方法:

  1. 自定义右键单击突出显示基于视图的 NSTableView
  2. 带菜单的NSTableView,如何右键更改边框颜色?
  3. 禁用 NSTableView 行对焦环
  4. NSTableView:蓝色轮廓右键单击行

我无法让其中任何一个工作,这可能是因为我无法子类化 NSTableView,而只能覆盖其属性和带有扩展的方法。到目前为止,我已经成功删除了默认的表格背景,例如:

extension NSTableView{
  open override func viewDidMoveToWindow() {
    super.viewDidMoveToWindow()

    //Remove default table styles
    backgroundColor = NSColor.clear
    enclosingScrollView!.drawsBackground = false
    selectionHighlightStyle = .none
  }
}

有什么方法可以删除 SwiftUI 中的右键单击边框吗?我什至愿意用其他视图覆盖它,但我似乎无法在表格单元格周围的空间中绘制 SwiftUI 视图。

I'm building a macOS app with SwiftUI, and I'm trying to remove (or even cover up) the border added to a List item when I right-click it.

Here it is by default:

List Row

Now with a right-click and a contextMenu view modifier:

List Row Right Click

I figured this is an NSTableView quirk, so I tried the approaches in these three Stack Overflow posts:

  1. Customize right click highlight on view-based NSTableView
  2. NSTableView with menu, how to change the border color with right click?
  3. Disabling the NSTableView row focus ring
  4. NSTableView: blue outline on right-clicked rows

I couldn't get any of those to work, and that may be due to the fact that I can't subclass an NSTableView, but can only override its properties and methods with an extension. Here's what I have so far that successfully removes the default table background and such:

extension NSTableView{
  open override func viewDidMoveToWindow() {
    super.viewDidMoveToWindow()

    //Remove default table styles
    backgroundColor = NSColor.clear
    enclosingScrollView!.drawsBackground = false
    selectionHighlightStyle = .none
  }
}

Is there any way to remove that right-click border in SwiftUI? I'm even open to covering it with other views, but I can't seem to draw SwiftUI views in that space around the table cell.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

上课铃就是安魂曲 2025-01-16 01:06:33

我找到了解决这个问题的方法。我将 List 放入 ZStack 中,然后将其 opacity 设置为零。然后,我构建了同一列表的完全自定义版本,但使用 LazyVStack:

//Message List
ZStack{
  //Ghost list for keyboard control
  List($model.messages, id: \.self, selection: $model.selectedMessages){ $message in
    MessageItemView(message: $message)
  }
  .focusable()
  .opacity(0)
  
  //Custom UI for the above List
  ScrollView{
    ZStack{ 
      LazyVStack(spacing: 5){
        ForEach($model.messagesToday){ $message in
          MessageItemView(message: $message)
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)

每个列表都绑定到同一模型,因此如果我单击一条消息来选择它自定义 UI,在不可见的 List 中选择相同的内容。 List 中表格使用的所有键盘快捷键看起来都适用于自定义版本。

那么这如何解决我原来的问题呢?您可以右键单击自定义 MessageItemView,单元格周围的默认环是不可见的,但 contextMenu 仍然有效(它在我的 MessageItemView 中定义) >)。

这并不像我想要的那么优雅,但是能够 100% 控制 UI,同时仍然获得 List 中免费提供的所有键盘控件,这很好。

I found a workaround for this. I put my List in a ZStack and then set its opacity to zero. I then built out a fully custom version of the same list, but using LazyVStack:

//Message List
ZStack{
  //Ghost list for keyboard control
  List($model.messages, id: \.self, selection: $model.selectedMessages){ $message in
    MessageItemView(message: $message)
  }
  .focusable()
  .opacity(0)
  
  //Custom UI for the above List
  ScrollView{
    ZStack{ 
      LazyVStack(spacing: 5){
        ForEach($model.messagesToday){ $message in
          MessageItemView(message: $message)
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)

Each list is bound to the same model, so if I click a message to select it in the custom UI, the same thing gets selected in the invisible List. All the keyboard shortcuts that come with table use in a List look like they are working on the custom version.

So how does this solve my original problem? You can right-click on the custom MessageItemView and the default ring around the cell is invisible, but the contextMenu still works (it's defined inside my MessageItemView).

This isn't as elegant as I'd like, but it's nice to have 100% control over the UI but still get all the keyboard controls that come for free with a List.

花落人断肠 2025-01-16 01:06:33
.onReceive(NotificationCenter.default.publisher(for: NSTableView.selectionIsChangingNotification)) { notification in
  if let tableView = notification.object as? NSTableView {
    tableView.selectionHighlightStyle = .none
  }
}

你可以用这个。它将重新加载您的列表。我正在寻找另一种方法,但这可行。

.onReceive(NotificationCenter.default.publisher(for: NSTableView.selectionIsChangingNotification)) { notification in
  if let tableView = notification.object as? NSTableView {
    tableView.selectionHighlightStyle = .none
  }
}

You can use this. It will reload your List. I'm looking for another approach but this works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文