【问题标题】:vertically aligning text in NSTableView row垂直对齐 NSTableView 行中的文本
【发布时间】:2010-01-20 16:42:09
【问题描述】:

我对 NSTableView 有一个小问题。当我在表格中增加一行的高度时,其中的文本在行的顶部对齐,但我想将它垂直居中对齐!

谁能给我建议??

谢谢,

米拉杰

【问题讨论】:

    标签: cocoa nstableview nstableviewcell


    【解决方案1】:

    这是一个简单的代码解决方案,它显示了一个子类,您可以使用它来居中对齐 TextFieldCell。

    标题

    #import <Cocoa/Cocoa.h>
    
    
    @interface MiddleAlignedTextFieldCell : NSTextFieldCell {
    
    }
    
    @end
    

    代码

    @implementation MiddleAlignedTextFieldCell
    
    - (NSRect)titleRectForBounds:(NSRect)theRect {
        NSRect titleFrame = [super titleRectForBounds:theRect];
        NSSize titleSize = [[self attributedStringValue] size];
        titleFrame.origin.y = theRect.origin.y - .5 + (theRect.size.height - titleSize.height) / 2.0;
        return titleFrame;
    }
    
    - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
        NSRect titleRect = [self titleRectForBounds:cellFrame];
        [[self attributedStringValue] drawInRect:titleRect];
    }
    
    @end
    

    This blog entry 展示了一个同样有效的替代解决方案。

    【讨论】:

    • size 假定宽度是无限的——它不考虑换行。我建议boundingRectForSize:options:,大小来自cellFrame
    【解决方案2】:

    这是基于上述答案构建的代码的 Swift 版本:

    import Foundation
    import Cocoa
    
    class VerticallyCenteredTextField : NSTextFieldCell
    {
    
        override func titleRectForBounds(theRect: NSRect) -> NSRect
        {
            var titleFrame = super.titleRectForBounds(theRect)
            var titleSize = self.attributedStringValue.size
            titleFrame.origin.y = theRect.origin.y - 1.0 + (theRect.size.height - titleSize.height) / 2.0
            return titleFrame
        }
    
        override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView)
        {
            var titleRect = self.titleRectForBounds(cellFrame)
    
            self.attributedStringValue.drawInRect(titleRect)
        }
    }
    

    然后我在NSTableView中设置tableView heightOfRow的高度:

    func tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat
    {
        return 30
    }
    

    将 NSTextFieldCell 的类设置为 VerticallyCenteredTextField:

    以及 TableViewCell 的高度

    感谢布莱恩的帮助。

    【讨论】:

      【解决方案3】:

      即使这是一个非常古老且答案已被接受的问题,这里有一个替代解决方案:

      进入 IB,选择位于 NSTableCellView 中的 NSTextField 并添加一个新的“Center Vertically in Container”约束。您还应该添加水平约束(可能应该将前导/尾随空间设置为 0 或任何适合您的需要)。

      在 NSOutlineView 中使用它并像魅力一样工作。就我而言,性能不是问题,因为我没有很多单元格,但我希望它不会比手动计算大小差。

      【讨论】:

        【解决方案4】:

        @iphaaw 为 Swift 4 更新了答案(注意,为了清楚起见,我还在类名末尾添加了“Cell”,这也需要与 Interface Builder 中的类名匹配):

        import Foundation
        import Cocoa
        
        class VerticallyCenteredTextFieldCell : NSTextFieldCell {
            override func titleRect(forBounds theRect: NSRect) -> NSRect {
                var titleFrame = super.titleRect(forBounds: theRect)
                let titleSize = self.attributedStringValue.size
                titleFrame.origin.y = theRect.origin.y - 1.0 + (theRect.size.height - titleSize().height) / 2.0
                return titleFrame
            }
        
            override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
                let titleRect = self.titleRect(forBounds: cellFrame)
                self.attributedStringValue.draw(in: titleRect)
            }
        }
        

        【讨论】:

          【解决方案5】:

          仅绘制属性字符串可能会对某些属性字符串产生奇怪的结果(例如带有上标)。

          我建议在 drawInterior 中调用 super...

            override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
              super.drawInterior(withFrame: self.titleRect(forBounds: cellFrame), in: controlView)
          }
          

          【讨论】:

            猜你喜欢
            • 2014-05-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-17
            • 2015-01-17
            • 2016-03-30
            • 2014-04-03
            • 1970-01-01
            相关资源
            最近更新 更多