jem*_*ons 23 cocoa nstextview osx-lion autolayout
我的应用程序包含一个NSScrollView文档视图,其中包含一些垂直堆叠的文件NSTextViews- 每个文本视图在添加文本时都会在垂直方向上调整大小.
目前,这都是在代码中管理的.该NSTextViews自动调整,但我观察他们调整大小有NSViewFrameDidChangeNotification,重计算其所有来源,使他们不重叠,并调整其上海华盈(滚动视图的文档视图),使它们都适合和可滚动到.
这似乎是自动布局的完美候选人!我NSLayoutConstraints在第一个文本视图和它的容器,最后一个文本视图及其容器之间设置,以及彼此之间的每个文本视图.然后,如果任何文本视图增长,它会自动"按下"它下面的文本视图的来源以满足约束,最终增加文档视图的大小,每个人都很高兴!
除此之外,似乎没有办法NSTextView在基于约束的布局中添加文本时自动增长?使用与NSTextView之前输入的文本自动扩展完全相同的内容,如果我没有为其高度指定约束,则将其自动解析为0并且不显示.如果我确实指定了约束,即使是不等式(例如> = 20),它仍然会停留在该大小,并且不会随着文本的添加而增长.
我怀疑这与NSTextView的实现有关-intrinsicContentSize,默认情况下会返回(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric).
所以我的问题是:如果我根据我的文本布局NSTextView返回更有意义intrinsicContentSize的子类,那么我的自动布局会按预期工作吗?
关于实现intrinsicContentSize垂直调整大小NSTextView的任何指针?
Ale*_*ubo 26
我正在进行一个非常相似的设置 - 包含文本视图的垂直堆栈视图,这些视图可以扩展以适应其文本内容并使用自动布局.
到目前为止,我不得不进行子类化NSTextView,这不是很干净,但在实践中表现非常出色:
- (NSSize) intrinsicContentSize {
NSTextContainer* textContainer = [self textContainer];
NSLayoutManager* layoutManager = [self layoutManager];
[layoutManager ensureLayoutForTextContainer: textContainer];
return [layoutManager usedRectForTextContainer: textContainer].size;
}
- (void) didChangeText {
[super didChangeText];
[self invalidateIntrinsicContentSize];
}
Run Code Online (Sandbox Code Playgroud)
添加时文本视图的初始大小addSubview,奇怪的是,不是内在大小; 我还没弄明白如何发出第一次失效(挂钩viewDidMoveToSuperview没有帮助),但我相信我最终会弄明白.
mar*_*rux 12
我有一个与NSTextField类似的问题,结果发现它是由于视图想要沿垂直方向紧紧拥抱其文本内容.因此,如果您将内容拥抱优先级设置为低于其他约束的优先级,则可能会有效.例如:
[textView setContentHuggingPriority:NSLayoutPriorityFittingSizeCompression-1.0 forOrientation:NSLayoutConstraintOrientationVertical];
Run Code Online (Sandbox Code Playgroud)
在Swift中,这将是:
setContentHuggingPriority(NSLayoutConstraint.Priority.fittingSizeCompression, for:NSLayoutConstraint.Orientation.vertical)
Run Code Online (Sandbox Code Playgroud)
以下是在Swift 3中使用自动布局制作扩展NSTextView的方法
textDidChange从NSTextDelegate.NSTextViewDelegate符合NSTextDelegate这个想法是textView有edges约束,这意味着每当它intrinsicContentSize发生变化时,它就会扩展它的父节点scrollView
import Cocoa
import Anchors
class TextView: NSTextView {
override var intrinsicContentSize: NSSize {
guard let manager = textContainer?.layoutManager else {
return .zero
}
manager.ensureLayout(for: textContainer!)
return manager.usedRect(for: textContainer!).size
}
}
class ViewController: NSViewController, NSTextViewDelegate {
@IBOutlet var textView: NSTextView!
@IBOutlet weak var scrollView: NSScrollView!
override func viewDidLoad() {
super.viewDidLoad()
textView.delegate = self
activate(
scrollView.anchor.top.constant(100),
scrollView.anchor.paddingHorizontally(30)
)
activate(
textView.anchor.edges
)
}
// MARK: - NSTextDelegate
func textDidChange(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else { return }
print(textView.intrinsicContentSize)
textView.invalidateIntrinsicContentSize()
}
}
Run Code Online (Sandbox Code Playgroud)类已准备好复制和粘贴。斯威夫特 4.2、macOS 10.14
class HuggingTextView: NSTextView, NSTextViewDelegate {
//MARK: - Initialization
override init(frame: NSRect) {
super.init(frame: frame)
delegate = self
}
override init(frame frameRect: NSRect, textContainer container: NSTextContainer?) {
super.init(frame: frameRect, textContainer: container)
delegate = self
}
required init?(coder: NSCoder) {
super.init(coder: coder)
delegate = self
}
//MARK: - Overriden
override var intrinsicContentSize: NSSize {
guard let container = textContainer, let manager = container.layoutManager else {
return super.intrinsicContentSize
}
manager.ensureLayout(for: container)
return manager.usedRect(for: container).size
}
//MARK: - NSTextViewDelegate
func textDidChange(_ notification: Notification) {
invalidateIntrinsicContentSize()
}
}
Run Code Online (Sandbox Code Playgroud)