【问题标题】:iOS/UIFont - reducing font widthiOS/UIFont - 减少字体宽度
【发布时间】:2012-04-21 06:12:53
【问题描述】:

我有一个固定大小的UILabel。不幸的是,在极少数情况下,我需要放入其中的文本不适合!我尝试过减小字体大小,但它需要减小很多,以至于看起来很糟糕。

是否可以以某种方式更改字体宽度? UIFont 似乎没有任何属性可以让我这样做?我需要使用 UIWebView 并使用 CSS 吗?我不太了解 CSS,因此如果这是解决此问题的最佳方法,我们将不胜感激。

或者,还有其他方法可以解决这个问题吗?

谢谢克雷格

【问题讨论】:

    标签: iphone ios cocoa-touch fonts uifont


    【解决方案1】:

    仅缩小文本宽度的最简单方法是对标签层应用变换:

    label.layer.transform = CATransform3DMakeScale(desiredWidth/textWidth, 1.0, 1.0);
    

    【讨论】:

      【解决方案2】:

      你的意思是你想在保持高度的同时水平挤压它吗?这是可以实现的,最高可达常规宽度的 60%。除此之外,它看起来很糟糕。

      这是 UILabel 子类的 drawRect,如果需要,它可以在任一轴上独立挤压。

      // This drawRect for a UILabel subclass reproduces most common UILabel formatting, but does not do truncation, line breaks, or scaling to fit.
      // Instead, it identifies cases where the label text is too large on either axis, and shrinks along that axis.
      // For small adjustments, this can keep text readable.  In extreme cases, it will create an ugly opaque block.
      - (void) drawRect:(CGRect)rect;
      {
          CGRect bounds = [self bounds];
          NSString *text = [self text];
          UIFont *font = [self font];
      
          // Find the space needed for all the text.
          CGSize textSize = [text sizeWithFont:font];
      
          // topLeft is the point from which the text will be drawn.  It may have to move due to compensate for scaling, or due to the chosen alignment.
          CGPoint topLeft = bounds.origin;
      
          // Default to no scaling.
          CGFloat scaleX = 1.0;
          CGFloat scaleY = 1.0;
      
          // If the text is too wide for its space, reduce it.
          // Remove the second half of this AND statement to have text scale WIDER than normal to fill the space.  Useless in most cases, but can be amusing.
          if ((textSize.width>0) && (bounds.size.width/textSize.width<1))
          {
              scaleX = bounds.size.width/textSize.width;
              topLeft.x /= scaleX;
          }
          else
          {
              // Alignment only matters if the label text doesn't already fill the space available.
              switch ([self textAlignment])
              {
                  case UITextAlignmentLeft :
                  {
                      topLeft.x = bounds.origin.x;
                  }
                      break;
      
                  case UITextAlignmentCenter :
                  {
                      topLeft.x = bounds.origin.x+(bounds.size.width-textSize.width)/2;
                  }
                      break;
      
                  case UITextAlignmentRight :
                  {
                      topLeft.x = bounds.origin.x+bounds.size.width-textSize.width;
                  }
                      break;
              }
          }
      
          // Also adjust the height if necessary.
          if ((textSize.height>0) && (bounds.size.height/textSize.height<1))
          {
              scaleY = bounds.size.height/textSize.height;
              topLeft.y /= scaleY;
          }
          else
          {
              // If the label does not fill the height, center it vertically.
              // A common feature request is for labels that do top or bottom alignment.  If this is needed, add a property for vertical alignment, and obey it here.
              topLeft.y = bounds.origin.y+(bounds.size.height-textSize.height)/2;
          }
      
          // Having calculated the transformations needed, apply them here.
          // All drawing that follows will be scaled.
          CGContextRef context = UIGraphicsGetCurrentContext();
          CGContextScaleCTM(context, scaleX, scaleY);
      
          // Begin drawing.
          // UILabels may have a shadow.
          if ([self shadowColor])
          {
              [[self shadowColor] set];
              CGPoint shadowTopLeft = CGPointMake(topLeft.x+[self shadowOffset].width/scaleX, topLeft.y+[self shadowOffset].height/scaleY);
              [text drawAtPoint:shadowTopLeft withFont:font];
          }
      
          // The text color may change with highlighting.
          UIColor *currentTextColor;
          if ((![self isHighlighted]) || (![self highlightedTextColor]))
              currentTextColor = [self textColor];
          else
              currentTextColor = [self highlightedTextColor];
      
          // Finally, draw the regular text.
          if (currentTextColor)
          {
              [currentTextColor set];
              [text drawAtPoint:topLeft withFont:font];
          }
      }
      

      【讨论】:

      • 感谢 Dondragmer,这正是我需要做的。我会试一试的。
      【解决方案3】:

      可以将UILabel的minimum font size设置为较小的值,勾选Autoshrink让它自动缩小。该参数在 Interface Builder 中可用。

      内部实现会减少字距,即字符之间的间距宽度。但它实际上并不能减小宽度。

      这是您最好的选择。如果您对结果仍然不满意。您可能需要更改您的设计。

      【讨论】:

      • 理论上,你也可以用 Quartz 2D 中的绘图替换你的标签,使用 CGContextSetCharacterSpacing,但这可能是 Craig 不感兴趣的东西(从美学上讲,如果你可以有负间距,我无法想象它会看起来不错)。我同意你的看法。改变设计。或者看看其他字体是否更窄。
      • @RobertRyan,我不知道这个选项。感谢您的意见!
      • 您好,感谢您的意见。正如我上面所说,我已经在减少字体,但我对这个解决方案并不满意。
      • 我会同时检查 Quartz 2D 选项。如果它允许我做我需要的,那么我会追求它。谢谢罗伯特。
      猜你喜欢
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      • 2012-06-20
      相关资源
      最近更新 更多