开发者

vertically aligning text in NSTableView row

开发者 https://www.devze.com 2022-12-17 19:21 出处:网络
I have a small problem with NSTableView. When I am increasing height of a row in table, the text in it is aligned at top 开发者_运维技巧of row but I want to align it vertically centered!

I have a small problem with NSTableView. When I am increasing height of a row in table, the text in it is aligned at top 开发者_运维技巧of row but I want to align it vertically centered!

Can anyone suggest me any way to do it ??

Thanks,

Miraaj


This is a simple code solution that shows a subclass you can use to middle align a TextFieldCell.

the header

#import <Cocoa/Cocoa.h>


@interface MiddleAlignedTextFieldCell : NSTextFieldCell {

}

@end

the code

@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 shows an alternative solution that also works well.


Here is the Swift version of the code building on the answer above:

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)
    }
}

Then I set the height of the tableView heightOfRow in the NSTableView:

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

Set the class of the NSTextFieldCell to be VerticallyCenteredTextField:

vertically aligning text in NSTableView row

and the height of the TableViewCell

vertically aligning text in NSTableView row

vertically aligning text in NSTableView row

Thanks Bryan for your help.


Even if this is a very old question with an accepted answer, here's an alternate solution:

Go into the IB, select your NSTextField sitting in a NSTableCellView and add a new "Center Vertically in Container" constraint. You should also add horizontal constraints (which should probably be leading/trailing space set to 0 or whatever suits your needs).

Used this in an NSOutlineView and worked like a charm. Performance wasn't an issue in my case, as I didn't have many cells, but I would expect it's not worse than manually calculating sizes.


@iphaaw's answer updated for Swift 4 (note I also added "Cell" on the end of the class name for clarity, which also needs to match the class name in 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)
    }
}


Just drawing the attributed string can yield strange results for some attributed strings (with superscript for example).

I’d suggest calling super in drawInterior…

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

精彩评论

暂无评论...
验证码 换一张
取 消