【问题标题】:NSTextFieldCell vertical alignment, solutions seem to squash the horizontal alignmentNSTextFieldCell 垂直对齐,解决方案似乎压扁了水平对齐
【发布时间】:2009-11-18 21:01:03
【问题描述】:

我有一个 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

替代解决方案是(从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

【问题讨论】:

    标签: objective-c cocoa interface-builder nstextfieldcell


    【解决方案1】:

    我发布了这个问题的答案,因为它确实有效,但是,我发现我找不到另一种方法来检查 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】:

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

      【讨论】:

      • 这需要我将演示文稿的那部分与我的数据层结合起来,老实说,我不确定我是否喜欢这样。这应该尊重 IB 中提供的选项,但由于某些原因它不是(就此而言,垂直对齐也应该是 IB 中的一个选项)。
      • 除了将 NSTextFieldCell 的字符串设置为模型层中的内容外,我不确定它是如何混合的。 :-) 对齐(和字体、颜色、大小……)是所有这些的一部分。但是,我同意垂直对齐应该是一种选择 - 提交增强报告。由于它不可用,您必须在绘图代码中说明它。
      【解决方案3】:

      similar question 中发布了一些潜在的解决方案,我不久前询问了这些解决方案。

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

      更新:

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

      解决方案是使用传递给方法的边界矩形中的origin.xsize.width

      在解决方案 #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;
      }
      

      【讨论】:

      • 我找到了我的解决方案之一,实际上是该问题的解决方案。
      • 我只是想弄清楚如何使用此解决方案保持水平对齐。但如果我不能,我可能不得不下山尝试另一条路线。
      • 我很惊讶水平对齐完全受这些解决方案的影响,因为它们都不会与 x 维度混淆。你是如何设置对齐方式的?
      • 在 Interface Builder 中,在列和单元格上。
      • 感谢有关解决方案 james 的更新,但仍然无法正确对齐。我确实确认 _cFlags.alignment 设置正确。值得注意的是,居中对齐仍然可以正常工作。
      猜你喜欢
      • 2012-10-10
      • 2013-11-25
      • 2014-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 2017-06-21
      相关资源
      最近更新 更多