我有一个 NSStackView ,其中装有 NSTextView 项。我正在尝试在父级NSView小于NSStackView时剪切stackview ,但是我没有运气。
这是我看到的两个问题场景:
1)完全不剪裁
我设置了NSView的框架:
let v = NSView(frame: NSMakeRect(0, 0, 1024.0, 768.0))
v.addSubview(rawStack)
即使父视图的大小似乎正确(我可以看到红色的bg颜色),stackView的大小也是完整的,并且没有被裁剪。
2)发生剪切,但是显示了错误的stackView子项
当我限制stackView 2的高度时,会发生奇怪的事情:
rawStack.heightAnchor.constraint(lessThanOrEqualToConstant: 768).isActive = true
a)当stackView太小时,它会增加一些stackView子级以填充剩余空间(不需要)。我可以通过仅在stackView太大时应用约束来解决此问题。
b)当stackView太大时,它将height=0
设置为错误的stackView子视图。我希望它可以显示孩子0,1,2,3,4
或适合的孩子数。而是显示2,3,5,6,7
。另外,我收到大量Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60000008bcc0 '# Tip top height' NSTextView:0x600000122f80.height >= 156.713 (active)>
我尝试设置NSStackView.setVisibilityPriority()
,该设置几乎奏效。问题是,如果不合适,它会隐藏整个子视图。如果需要,我希望将其部分裁剪。
有什么想法吗?
当前代码:
func swapView(newView:NSView) {
let viewToShowNext = generateDetailSlide(newView: newView)
scrollView.documentView = viewToShowNext
}
func generateDetailSlide(newView:NSView) -> FlippedView {
let rawStack = newView as! FlippedStackView
rawStack.identifier = NSUserInterfaceItemIdentifier(rawValue: "RAWSTACK###")
if (rawStack.frame.size.height > 768) {
// rawStack.heightAnchor.constraint(lessThanOrEqualToConstant: 768).isActive = true
}
rawStack.widthAnchor.constraint(lessThanOrEqualToConstant: 1024).isActive = true
for (i,view) in rawStack.arrangedSubviews.enumerated() {
Swift.print("### Frame", view.frame)
Swift.print("### Bounds", view.bounds)
//view.widthAnchor.constraint(equalToConstant: 700.0)
let length = rawStack.arrangedSubviews.count
let priority = Float(length - i) // highest priority for lowest items
// hide any beyond 4
view.setContentCompressionResistancePriority(.init(rawValue: priority * 1000), for: .vertical)
view.exerciseAmbiguityInLayout() // try this?!?
// rawStack.setVisibilityPriority(.init(rawValue: priority), for: view)
}
rawStack.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
Swift.print("clippingResistance", rawStack.clippingResistancePriority(for: .vertical))
rawStack.layoutSubtreeIfNeeded()
let v = NSView(frame: NSMakeRect(0, 0, 1024.0, 768.0))
v.addSubview(rawStack)
return v
}
func makeTextField(content: String, type:String, globalConfig: GlobalConfig) -> NSTextView {
var style = getStringFromDict(cssObj: globalConfig.defaultStyles)
var html = "<span style=\"\(style)\">\(content)</span>"
let titleData = Data(html.utf8)
let NSAttrStr = try? NSMutableAttributedString(data: titleData, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)
let textStorage:NSTextStorage = NSTextStorage(attributedString: NSAttrStr!)
let manager:NSLayoutManager = NSLayoutManager()
let container:NSTextContainer = NSTextContainer(containerSize: NSMakeSize(800, 400))
// tie it all together so text shows up
textStorage.addLayoutManager(manager)
manager.addTextContainer(container)
// appears to have no effect? These sizes don't seem to matter...
let windowFrame:NSRect = NSRect(x: 0, y: 0, width: 800, height: 200)
let textView:NSTextView = NSTextView(frame: windowFrame, textContainer: container)
textView.backgroundColor = globalConfig.bgColor
textView.isEditable = false
textView.alignment = .left
// get size of textView content. This works!
textView.layoutManager?.ensureLayout(for: container)
let sz = textView.layoutManager?.usedRect(for: container).size
let c1 = textView.heightAnchor.constraint(greaterThanOrEqualToConstant: (sz?.height)!)
c1.isActive = true
c1.identifier = "\(content) height"
// does this one even make a difference?
let c2 = textView.widthAnchor.constraint(greaterThanOrEqualToConstant: ((sz?.width)! + 20))
c2.isActive = true
c2.identifier = "\(content) width"
return textView
}