9

我有一个 NSTextFieldCell 我希望以中间垂直对齐方式显示。感谢这里的一个较旧的问题和一个博客条目,我有两个可行的解决方案。

但是,这两种解决方案似乎都削弱了我将单元格设置为右对齐的能力。谁能帮助我使这些解决方案中的任何一个都支持两种对齐形式?

这是一种解决方案的代码:

@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

替代解决方案是(从这个博客获得):

@implementation RSVerticallyCenteredTextFieldCell

- (NSRect)drawingRectForBounds:(NSRect)theRect
{
    NSRect newRect = [super drawingRectForBounds:theRect];

    if (mIsEditingOrSelecting == NO)
    {
        // Get our ideal size for current text
        NSSize textSize = [self cellSizeForBounds:theRect];

        // Center that in the proposed rect
        float heightDelta = newRect.size.height - textSize.height;  
        if (heightDelta > 0)
        {
            newRect.size.height -= heightDelta;
            newRect.origin.y += (heightDelta / 2);
        }
    }

    return newRect;
}

- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength
{
    aRect = [self drawingRectForBounds:aRect];
    mIsEditingOrSelecting = YES;    
    [super selectWithFrame:aRect inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
    mIsEditingOrSelecting = NO;
}

- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent
{   
    aRect = [self drawingRectForBounds:aRect];
    mIsEditingOrSelecting = YES;
    [super editWithFrame:aRect inView:controlView editor:textObj delegate:anObject event:theEvent];
    mIsEditingOrSelecting = NO;
}

@end
4

3 回答 3

5

我发布了这个问题的答案,因为它确实有效,但是,我发现我找不到另一种方法来检查 IB 的对齐设置这一事实非常烦人。访问 _cFlags 似乎有点脏,我很想找到一种更清洁的方法。

基于此博客条目之前发布的代码。

- (NSRect)drawingRectForBounds:(NSRect)theRect
{
    // Get the parent's idea of where we should draw
    NSRect newRect = [super drawingRectForBounds:theRect];

    if (mIsEditingOrSelecting == NO)
    {
        // Get our ideal size for current text
        NSSize textSize = [self cellSizeForBounds:theRect];

        // Center that in the proposed rect
        float heightDelta = newRect.size.height - textSize.height;  
        if (heightDelta > 0)
        {
            newRect.size.height -= heightDelta;
            newRect.origin.y += (heightDelta / 2);
        }

        // For some reason right aligned text doesn't work.  This section makes it work if set in IB.
        // HACK: using _cFlags isn't a great idea, but I couldn't find another way to find the alignment.
        // TODO: replace _cFlags usage if a better solution is found.
        float widthDelta = newRect.size.width - textSize.width;
        if (_cFlags.alignment == NSRightTextAlignment && widthDelta > 0) {
            newRect.size.width -= widthDelta;
            newRect.origin.x += widthDelta;
        }

    }

    return newRect;
}
于 2009-11-19T16:48:23.510 回答
3

您可以使用 NSParagraphStyle/NSMutableParagraphStyle 设置对齐方式(和其他属性)。将适当配置的 NSParagraphStyle 对象添加到属性字符串的全部范围。

于 2009-11-19T00:30:26.837 回答
2

在我不久前问过的类似问题中发布了一些潜在的解决方案。

老实说,我仍然使用未记录的_cFlags.vCentered布尔值(tsk tsk,糟糕的程序员!)来完成工作。这很简单,而且有效。如果必须的话,我稍后会重新发明轮子。

更新:

好的,我想我已经想通了。两种解决方案都依赖于调用来super获取默认矩形,然后修改origin.ysize.height执行垂直居中。但是,对 的调用会super返回一个矩形,其宽度已经调整为水平适合文本。

解决方案是使用origin.xand size.widthfrom 传递给方法的边界矩形:

在解决方案 #1 中:

- (NSRect)titleRectForBounds:(NSRect)theRect {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];

    // modified:
    theRect.origin.y += (theRect.size.height - titleSize.height)/2.0 - 0.5;
    return theRect;
}

在解决方案 #2 中:

- (NSRect)drawingRectForBounds:(NSRect)theRect
{
    NSRect newRect = [super drawingRectForBounds:theRect];

    // modified:
    newRect.origin.x = theRect.origin.x;
    newRect.size.width = theRect.size.width;

    if (mIsEditingOrSelecting == NO)
    {
        // Get our ideal size for current text
        NSSize textSize = [self cellSizeForBounds:theRect];

        // Center that in the proposed rect
        float heightDelta = newRect.size.height - textSize.height;  
        if (heightDelta > 0)
        {
            newRect.size.height -= heightDelta;
            newRect.origin.y += (heightDelta / 2);
        }
    }

    return newRect;
}
于 2009-11-19T05:20:08.890 回答