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
nativeText
,布局工作正常,这表明问题出在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
。