代码之家  ›  专栏  ›  技术社区  ›  Bryan McLemore

NSTextFieldCell垂直对齐,解决方案似乎挤压了水平对齐

  •  9
  • Bryan McLemore  · 技术社区  · 16 年前

    然而,这两种解决方案似乎都挤压了我将单元格设置为右对齐的能力。有谁能帮助我使这两种解决方案中的任何一种都支持这两种对齐方式吗?

    以下是一个解决方案的代码:

    @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 ):

    @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
    
    3 回复  |  直到 16 年前
        1
  •  5
  •   Bryan McLemore    16 年前

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

    基于先前从发布的代码 this blog entry .

    - (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;
    }
    
        2
  •  3
  •   Joshua Nozzi    16 年前

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

        3
  •  2
  •   Community Mohan Dere    8 年前

    有几个潜在的解决方案张贴在 similar question

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

    好的,我想我已经明白了。这两种解决方案都依赖于对 super origin.y size.height 执行垂直对中。呼吁 超级的

    解决办法是使用 origin.x size.width 从传入方法的bounds rect:

    - (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;
    }