NSTextView与NSTextTable:通过水平滚动设置最小宽度?

时间:2020-07-31 11:05:54

标签: cocoa autolayout nsattributedstring nstextview nsscrollview

我有一个带有NSTextView的可可应用。我显示了一个很大的表(通过NSAttributedStringNSTextTableNSTextTableBlock制成)。

我想要实现以下行为:

  1. 让表格在文本视图的整个宽度上展开,每列的宽度相同
  2. 为table / textView设置最小宽度,以防止在用户调整窗口大小并使窗口很小时将表挤压在一起;而是显示水平滚动条。

我设法使#1正常工作或使#2正常工作,但是我无法弄清楚如何使文本视图的最小宽度同时使表格在整个宽度上伸展。

squished table

我的代码:

最小宽度,可滚动,但不能扩展到整个宽度:

self.textView.textStorage?.setAttributedString(tableString)
           
self.textView.textContainer?.widthTracksTextView = false
self.textView.isHorizontallyResizable = true

cellBlock.setValue(200, type: .absoluteValueType, for: .minimumWidth)

扩展为整个宽度,但未强制使用最小宽度:

self.textView.isHorizontallyResizable = true
cellBlock.setValue(relativeWidth, type: .percentageValueType, for: .width)

我还尝试为文本视图设置Autolayout约束,但这仅强制使用minWidth,而不显示水平滚动条。

1 个答案:

答案 0 :(得分:0)

其他内容呢?喜欢表格上方/下方的文字吗?收缩?保持与桌子相同的最小宽度?我的假设是与桌子的宽度相同。

下面的示例不是一个完整的答案,请将其视为您必须首先进行的概念验证。

屏幕录像

很抱歉,GIF的质量为2MB。

enter image description here

示例项目

  • 是否在IB中添加了文本视图并将其连接到插座
  • 其余操作均在代码中完成

重要部位

滚动器

同时设置它们并根据内容自动隐藏。

scrollView.hasVerticalScroller = true
scrollView.hasHorizontalScroller = true
scrollView.autohidesScrollers = true

切换文本视图的大小和设置容器大小<​​/ h3>

由于viewDidLayout覆盖等原因,这是一个la脚的实现。例如,如果您调整鼠标和窗口大小的速度足够快,那么最终的大小可能会小于300,等等。

这里的重要部分是我更改了哪些属性,并在达到阈值时坚持使用固定的containerSize(水平)。

if textView.bounds.size.width > 300 {
    textView.isHorizontallyResizable = false
    textView.textContainer?.widthTracksTextView = true
} else {
    textView.textContainer?.widthTracksTextView = false
    textView.isHorizontallyResizable = true
    textView.textContainer?.containerSize = NSSize(width: textView.bounds.size.width, height: CGFloat.greatestFiniteMagnitude)
}

完整代码

import Cocoa

class ViewController: NSViewController {
    @IBOutlet var scrollView: NSScrollView!
    @IBOutlet var textView: NSTextView!
    
    let loremIpsum = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.\n"
    let loremIpsumCell = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.\n"
        
    override func viewDidLayout() {
        super.viewDidLayout()
        
        if textView.bounds.size.width > 300 {
            textView.isHorizontallyResizable = false
            textView.textContainer?.widthTracksTextView = true
        } else {
            textView.textContainer?.widthTracksTextView = false
            textView.isHorizontallyResizable = true
            textView.textContainer?.containerSize = NSSize(width: textView.bounds.size.width, height: CGFloat.greatestFiniteMagnitude)
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        scrollView.hasVerticalScroller = true
        scrollView.hasHorizontalScroller = true
        scrollView.autohidesScrollers = true
        
        let content = NSMutableAttributedString(string: loremIpsum)
        
        let table  = NSTextTable()
        table.numberOfColumns = 2
        table.setContentWidth(100, type: .percentageValueType)

        (0...1).forEach { row in
            (0...5).forEach { column in
                let block = NSTextTableBlock(table: table, startingRow: row, rowSpan: 1, startingColumn: column, columnSpan: 1)
                block.setWidth(1.0, type: .absoluteValueType, for: .border)
                block.setBorderColor(.orange)
                
                let paragraph = NSMutableParagraphStyle()
                paragraph.textBlocks = [block]

                let cell = NSMutableAttributedString(string: loremIpsumCell, attributes: [.paragraphStyle: paragraph])
                content.append(cell)
            }
        }
        
        content.append(NSAttributedString(string: loremIpsum))
        
        textView.textStorage?.setAttributedString(content)
    }
}
相关问题