У меня есть NSStackView , заполненный NSTextView элементами.Я пытаюсь обрезать представление стека, когда родительский NSView меньше , чем NSStackView, но мне не везет.
Вот 2 сценария проблемы, которые я вижу:
1) Нет отсечения вообще
Я установил кадр NSView:
let v = NSView(frame: NSMakeRect(0, 0, 1024.0, 768.0))
v.addSubview(rawStack)
stackView является полноразмерным и НЕ обрезается, даже если родительское представление кажется размеромправильно (я вижу красный цвет bg).
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
}