【问题标题】:How to draw vertical text in UILabel如何在 UILabel 中绘制垂直文本
【发布时间】:2012-03-09 03:50:29
【问题描述】:

我目前正致力于在标签中绘制竖排中文文本。这是我想要实现的目标,尽管是中文字符:

我一直在计划绘制每个字符,将每个字符向左旋转 90 度,然后通过仿射变换旋转整个标签以获得最终结果。但是,感觉非常复杂。有没有一种更简单的方法来绘制文本而没有我所缺少的复杂的 CoreGraphics 魔法?

【问题讨论】:

  • 你正在做的很好。它并不复杂

标签: iphone core-graphics uilabel


【解决方案1】:

好吧,你可以这样做:

labelObject.numberOfLines = 0;
labelObject.lineBreakMode = NSLineBreakByCharWrapping;

和 setFrame 与 --height:100, width:20 它会正常工作..

【讨论】:

  • 笨拙,但我最终还是这样做了。
  • 自 iOS 6.0 UILineBreakModeCharacterWrap 已弃用。请改用NSLineBreakByCharWrapping
【解决方案2】:

有效

UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 30, 100)];
lbl.transform = CGAffineTransformMakeRotation((M_PI)/2);

【讨论】:

  • +1,虽然这并不能完全回答 OP 的问题(这也会旋转字符,而他显然想要列样式的文本),但对于像我这样真正想要的其他人来说,这是一个非常有用的答案旋转的文本
【解决方案3】:

尝试了 Simha.IC 提供的方法,但对我来说效果不佳。有些字符比其他字符更薄,并被放置在一条线上。例如

W
ai
ti
n
g

我的解决方案是创建一个方法,通过在每个字符后添加\n 将字符串本身转换为多行文本。方法如下:

- (NSString *)transformStringToVertical:(NSString *)originalString
{
    NSMutableString *mutableString = [NSMutableString stringWithString:originalString];
    NSRange stringRange = [mutableString rangeOfString:mutableString];

    for (int i = 1; i < stringRange.length*2 - 2; i+=2)
    {
        [mutableString insertString:@"\n" atIndex:i];
    }

    return mutableString;
}

然后你只需像这样设置标签:

label.text = [self transformStringToVertical:myString];
CGRect labelFrame = label.frame;
labelFrame.size.width  = label.font.pointSize;
labelFrame.size.height = label.font.lineHeight * myString.length;
label.frame = labelFrame;

享受吧!

【讨论】:

  • 我使用了这种方法,但在 Swift 3.0 中使用:var newString:String = ""for i in 0 ..&lt; originalString.characters.count{newString += "\(originalString[originalString.index(originalString.startIndex, offsetBy: i)])\n" }
【解决方案4】:

如果你想旋转整个标签(包括字符),你可以这样做:

  1. 首先将 QuartzCore 库添加到您的项目中。
  2. 创建标签:

    UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 300.0, 30.0)];
    [label setText:@"Label Text"];
    
  3. 旋转标签:

    [label setTransform:CGAffineTransformMakeRotation(-M_PI / 2)];
    

根据您希望如何放置标签,您可能需要设置锚点。这设置了发生旋转的点。例如:

    [label.layer setAnchorPoint:CGPointMake(0.0, 1.0)];

【讨论】:

  • 所有答案都有效,但这是最好的答案。我做了(-m_pi/4),看起来很酷。谢谢
【解决方案5】:

这是绘制垂直文本的另一种方法,通过子类化UILabel。但这与问题想要的有所不同。

目标-C

@implementation MyVerticalLabel

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGAffineTransform transform = CGAffineTransformMakeRotation(-M_PI_2);
    CGContextConcatCTM(context, transform);
    CGContextTranslateCTM(context, -rect.size.height, 0);

    CGRect newRect = CGRectApplyAffineTransform(rect, transform);
    newRect.origin = CGPointZero;

    NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
    textStyle.lineBreakMode = self.lineBreakMode;
    textStyle.alignment = self.textAlignment;

    NSDictionary *attributeDict =
    @{
      NSFontAttributeName : self.font,
      NSForegroundColorAttributeName : self.textColor,
      NSParagraphStyleAttributeName : textStyle,
      };
    [self.text drawInRect:newRect withAttributes:attributeDict];
}
@end

示例图片如下:

斯威夫特

它可以放在故事板上,直接观看结果。像图像一样,它的框架将包含垂直文本。文本属性,如textAlignmentfont,也很有效。

@IBDesignable
class MyVerticalLabel: UILabel {

    override func drawRect(rect: CGRect) {
        guard let text = self.text else {
            return
        }

        // Drawing code
        let context = UIGraphicsGetCurrentContext()

        let transform = CGAffineTransformMakeRotation( CGFloat(-M_PI_2))
        CGContextConcatCTM(context, transform)
        CGContextTranslateCTM(context, -rect.size.height, 0)

        var newRect = CGRectApplyAffineTransform(rect, transform)
        newRect.origin = CGPointZero

        let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle
        textStyle.lineBreakMode = self.lineBreakMode
        textStyle.alignment = self.textAlignment

        let attributeDict: [String:AnyObject] = [
            NSFontAttributeName: self.font,
            NSForegroundColorAttributeName: self.textColor,
            NSParagraphStyleAttributeName: textStyle,
        ]

        let nsStr = text as NSString
        nsStr.drawInRect(newRect, withAttributes: attributeDict)
    }

}

斯威夫特 4

override func draw(_ rect: CGRect) {
    guard let text = self.text else {
        return
    }

    // Drawing code
    if let context = UIGraphicsGetCurrentContext() {
        let transform = CGAffineTransform( rotationAngle: CGFloat(-Double.pi/2))
        context.concatenate(transform)
        context.translateBy(x: -rect.size.height, y: 0)
        var newRect = rect.applying(transform)
        newRect.origin = CGPoint.zero

        let textStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
        textStyle.lineBreakMode = self.lineBreakMode
        textStyle.alignment = self.textAlignment

        let attributeDict: [NSAttributedStringKey: AnyObject] = [NSAttributedStringKey.font: self.font, NSAttributedStringKey.foregroundColor: self.textColor, NSAttributedStringKey.paragraphStyle: textStyle]

        let nsStr = text as NSString
        nsStr.draw(in: newRect, withAttributes: attributeDict)
    }
}

【讨论】:

    【解决方案6】:

    斯威夫特 5

    使用 CGAffineTransform 更简单的方法

    import UIKit
    class ViewController: UIViewController {
    
    @IBOutlet weak var verticalText: UILabel
    
        override func viewDidLoad() {
    
            verticalText.transform = CGAffineTransform(rotationAngle:CGFloat.pi/2)
        }
    }
    

    【讨论】:

      【解决方案7】:
      import UIKit
      
      class VerticalLabel : UILabel {
          
          private var _text : String? = nil
          
          override var text : String? {
              get {
                  return _text
              }
              set {
                  self.numberOfLines = 0
                  self.textAlignment = .center
                  self.lineBreakMode = .byWordWrapping
                  _text = newValue
                  if let t = _text {
                      var s = ""
                      for c in t {
                          s += "\(c)\n"
                      }
                      super.text = s
                  }
              }
          }
          
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-16
        • 2015-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-04
        • 2022-01-05
        • 1970-01-01
        相关资源
        最近更新 更多