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

3
我正在使用SwiftUI构建一个macOS应用程序,并尝试在右键单击List项时删除(或甚至覆盖)添加的边框。
以下是默认情况下的效果:

List Row

现在只需右键单击和使用contextMenu视图修饰符:

List Row Right Click

我想这是一个NSTableView的怪癖,所以我尝试了这三个Stack Overflow帖子中的方法:
  1. 自定义基于视图的NSTableView中右键单击高亮显示
  2. 带菜单的NSTableView,如何通过右键单击更改边框颜色?
  3. 禁用NSTableView行焦点环
  4. NSTableView:右键单击行时出现蓝色轮廓
我无法让它们中的任何一个起作用,这可能是因为我无法对NSTableView进行子类化,而只能使用extension覆盖其属性和方法。到目前为止,我已经成功删除了默认表格背景等内容:
extension NSTableView{
  open override func viewDidMoveToWindow() {
    super.viewDidMoveToWindow()

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

有没有办法在SwiftUI中去除右键边框?我甚至可以用其他视图覆盖它,但我似乎无法在表格单元格周围的空间中绘制SwiftUI视图。

你能找到解决方案吗? - Euan Traynor
@EuanTraynor 我找到了一个解决方法。我会将其发布为答案,因为它包含一些代码。 - Clifton Labrum
感谢NSTableView的扩展!我不知道AppKit是如何工作的,但我一直在努力尝试去除默认的选择高亮... SwiftUI的解决方案(特别是.listRowBackground(Color.clear))在iOS和iPadOS上运行良好,但在AppKit上却很棘手... - domi852
2个回答

1

我找到了一个解决方法。我把我的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中单击一个message来选择它,则不可见的List中也会选择相同的内容。所有与表格使用的键盘快捷键在List中使用时都能正常工作。
那么这如何解决我的原始问题呢?您可以右键单击自定义的MessageItemView,默认的单元格周围的环形是不可见的,但是contextMenu仍然有效(它在我的MessageItemView内定义)。
这并不像我想要的那么优雅,但是拥有对UI的100%控制,并且仍然获得与List免费提供的所有键盘控件非常好。

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

你可以使用这个。它会重新加载你的列表。我在寻找另一种方法,但这个是有效的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接