【问题标题】:How to get NSTextField to wrap in variable row height table如何让 NSTextField 包含在可变行高表中
【发布时间】:2019-04-25 04:38:55
【问题描述】:

我需要将文本包装在 NSTable 的行中。我读了: SO How to update row heights...

和: View-based NSTableView with rows that have dynamic height...

我的行高适用于多行文本(带有 eols),但如果我省略 eols 则不行。 (使用精简的测试用例,直到我弄明白为止。)

这是我的演示代码:

class TableCellView: NSTableCellView {
    var title = NSTextField()

    convenience init(_ id: NSUserInterfaceItemIdentifier, itemCount: Int) {
        self.init(frame: .zero)
        identifier = id
        rowSizeStyle = .custom

        addSubview(title)
        var s = "\(itemCount):\n"
        for item in 0...(5 + itemCount) { s += "\(item)) Text written to a scrollable table view " }

        let a = NSAttributedString(string: s, attributes: [NSAttributedString.Key.font : NSFont.systemFont(ofSize: 18.0)] )

        title.attributedStringValue = a
        title.textColor = NSColor.textColor

        title.backgroundColor = NSColor.clear
        title.translatesAutoresizingMaskIntoConstraints = false
        title.isBordered = false

        title.widthAnchor.constraint(equalTo: widthAnchor, constant: 0).isActive = true
        title.topAnchor.constraint(equalTo: topAnchor, constant: 1).isActive = true
        title.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }
}

class TableViewManager: NSObject, NSTableViewDataSource, NSTableViewDelegate, Actor {
    weak var actorDelegate: ActorDelegate?

    var identifier: NSUserInterfaceItemIdentifier? = Identifier.View.tableDelegate
    var count = 0

    func numberOfRows(in tableView: NSTableView) -> Int {

        return 10
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let id = tableColumn!.identifier
        var view = tableView.makeView(withIdentifier: id, owner: nil) as? TableCellView
        if view == nil {
            view = TableCellView(id, itemCount: count)
        }

        count += 1      
        return view
    }
}

class TableViewController: NSViewController {
    private let tableViewDelegate = TableViewManager()
    var scrollView: ScrollableTableView!
    var tableView: NSTableView { get { return scrollView.tableView } }

    // Initialize the table scroll view
    convenience init(_ identifier: NSUserInterfaceItemIdentifier) {
        self.init()
        self.identifier = identifier
        scrollView = ScrollableTableView(cols: [(500, "Commit")], delegate: tableViewDelegate, source: tableViewDelegate)
        view = scrollView

        tableView.rowSizeStyle = .custom
        tableView.usesAutomaticRowHeights = true
        tableView.rowHeight = 18
        tableView.headerView = nil  // Get rid of header
        tableView.usesAlternatingRowBackgroundColors = true
    }
    // Pass along reload data
    func reloadData() { tableView.reloadData() }
}

【问题讨论】:

    标签: swift nstableview macos-mojave


    【解决方案1】:

    终于想出了一个解决方案,但我很想请一位真正的专家告诉我它是否强大。 (直到快速和肮脏的常量)。我覆盖了表格单元格的绘制,对其初始化器进行了一些修改,如下所示:

    
    class TableCellView: NSTableCellView {
        var title = NSTextField()
        var height: NSLayoutConstraint!
    
        convenience init(_ id: NSUserInterfaceItemIdentifier, itemCount: Int) {
            self.init(frame: .zero)
            identifier = id
            rowSizeStyle = .custom
    
            addSubview(title)
            var s = "\(itemCount):\n"
            for item in 0...(5 + itemCount) { s += "\(item)) Text written to a scrollable table view " }
    
            let a = NSAttributedString(string: s, attributes: [NSAttributedString.Key.font : NSFont.systemFont(ofSize: 18.0)] )
    
            title.attributedStringValue = a
            title.textColor = NSColor.textColor
    
            title.backgroundColor = NSColor.clear
            title.translatesAutoresizingMaskIntoConstraints = false
            title.isBordered = false
            title.font = NSFont.systemFont(ofSize: 14.0)
    
            title.widthAnchor.constraint(equalTo: widthAnchor, constant: 1).isActive = true
            title.topAnchor.constraint(equalTo: topAnchor).isActive = true
            title.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
            height = heightAnchor.constraint(equalToConstant: 100)  // Value doesn't matter, gets recalculated by override draw
            height.isActive = true
        }
    
        override func draw(_ dirtyRect: NSRect) {
            // Will recalculate height, but parameter must be larger than result
            let bound = title.attributedStringValue.boundingRect(with: NSSize(width: frame.width, height: 4096), options: [.usesLineFragmentOrigin, .usesFontLeading])
            height.constant = bound.height + 2.0
            super.draw(dirtyRect)
        }
    }
    

    结果如下所示:

    并在我调整窗口大小时正确重新换行。

    希望这对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      • 2014-07-31
      • 2020-07-06
      • 2021-11-24
      相关资源
      最近更新 更多