Macos 如何使用NSViewRepresentable在SwiftUI视图中垂直居中NSTextView?

Macos 如何使用NSViewRepresentable在SwiftUI视图中垂直居中NSTextView?,macos,swiftui,nstextview,Macos,Swiftui,Nstextview,我有一个简单的NSViewRepresentable,它包装了一个NSTextView struct TextView:NSViewRepresentable{ typealias NSViewType=NSTextView 变量文本:NSAttributedString func makeNSView(上下文:context)->NSTextView{ let view=NSTextView() //设置背景色以显示视图边界 view.backgroundColor=NSColor.syste

我有一个简单的
NSViewRepresentable
,它包装了一个
NSTextView

struct TextView:NSViewRepresentable{
typealias NSViewType=NSTextView
变量文本:NSAttributedString
func makeNSView(上下文:context)->NSTextView{
let view=NSTextView()
//设置背景色以显示视图边界
view.backgroundColor=NSColor.systemBlue
view.drawsBackground=true
view.isEditable=false
view.isSelectable=false
返回视图
}
func updateNSView(nsView:NSTextView,context:context){
nsView.textStorage?.setAttributedString(文本)
}
}
我想使它垂直居中,所以我使用了一个
VStack
,上面和下面都有
spacer
。 我希望它的左右边距与窗口大小成比例,因此我将它包装在
GeometryReader
frame()

struct ContentView:View{
func textView()->某些视图{
让text=”“”
Lorem ipsum dolor sit amet,一位杰出的领导者,一位伟大的领袖\
暂时性的劳工和财产损失。
"""
//注意:实际应用程序的文本比此复杂,*不*使用
//NSAttributeString并不是一个真正的选项,至少在SwiftUI出现之前是这样
//适当的富文本支持。
let size:CGFloat=18
let font=NSFont(名称:“LeagueSpartan Bold”,大小:size)
让attrString=NSAttributeString(
字符串:文本,
属性:[.foregroundColor:NSColor.systemYellow,
.font:font??NSFont.systemFont(ofSize:size)])
返回文本视图(文本:attrString)
}
var body:一些观点{
让textView:some View=self.textView()
返回ZStack{
//使用ZStack提供窗口背景色
颜色(NSColor.systemTeal)
VStack{
垫片()
GeometryReader{m2英寸
textView.框架(宽度:m2.size.width/1.618)
}
垫片()
}
}
}
}
水平框架工作正常,但垂直间距根本不起作用:

(初始状态)

调整窗口大小会产生恶作剧:

(从底部调整大小)

(从下到上调整大小,然后再向下调整)

哦,而且预览完全是疯狂的:

如果我将自定义的
TextView
替换为
SwiftUI
native
Text
,布局工作正常,这表明问题出在
TextView
中。(请注意,默认窗口大小较小。)

似乎
NSTextView
的大小设置不正确。如果我将
nsView.sizeToFit()
添加到
updateNSView()

func updateNSView(\nsView:NSTextView,context:context){
nsView.textStorage?.setAttributedString(文本)
nsView.sizeToFit()
}
这会使我获得较小的默认窗口大小,并在我上下调整大小时阻止文本反弹到窗口底部,但文本仍固定在窗口顶部附近,预览仍被破坏,从底部调整大小仍会使
NSTextView
临时填充窗口的大部分高度

我试过摆弄的其他东西:
isVerticallyResizable
setContentCompressionResistancePriority
autoresizingMask
translatesAutoresizingMaskIntoConstraints
invalidateintrisccontentsize
。所有这些似乎都没有明显的区别


似乎我想要的是在包含的SwiftUI视图调整大小时更新
NSTextView
大小,但似乎没有任何明显的方法可以做到这一点,而且我可能是错的。

如果您只需要显示
NSAttributedString
,正如我所理解的,然后基于
NSTextField
的方法,如下所示,更合适,因为
NSTextView
没有默认的内部布局,需要显式的外部框架

这里是修改后的表示,
ContentView
不需要更改

struct TextView: NSViewRepresentable {
  typealias NSViewType = NSTextField

  var text: NSAttributedString

  func makeNSView(context: Context) -> NSTextField {
    let view = NSTextField()
    // set background color to show view bounds
    view.backgroundColor = NSColor.systemBlue
    view.drawsBackground = true
    view.isEditable = false
    view.isSelectable = false
    view.lineBreakMode = .byWordWrapping
    view.maximumNumberOfLines = 0
    view.translatesAutoresizingMaskIntoConstraints = false
    view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
    view.setContentCompressionResistancePriority(.required, for: .vertical)
    return view
  }

  func updateNSView(_ nsView: NSTextField, context: Context) {
    nsView.attributedStringValue = text
  }
}

这很有效。奇怪的是,它仍然没有为我定心,而是在
ContentView
中的
GeometryReader
中添加了一个
HStack
。为了获得我想要的外观,我还必须设置
view.isBezeled=false