Как нарисовать вертикальный текст в UILabel - PullRequest
26 голосов
/ 09 марта 2012

В настоящее время я работаю над рисованием вертикального китайского текста в метке. Вот что я пытаюсь достичь, хотя и с китайскими иероглифами:

Express

Я планировал нарисовать каждый символ, повернуть каждый символ на 90 градусов влево, а затем повернуть всю метку с помощью аффинных преобразований, чтобы получить окончательный результат. Однако это ужасно сложно. Есть ли более простой способ рисовать текст без сложной магии CoreGraphics, которую мне не хватает?

Ответы [ 5 ]

36 голосов
/ 09 марта 2012

Ну, вы можете сделать, как показано ниже:

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

и setFrame с - высота: 100, ширина: 20 Это будет работать нормально ..

21 голосов
/ 09 марта 2012

Работает

UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 30, 100)];
lbl.transform = CGAffineTransformMakeRotation((M_PI)/2);
11 голосов
/ 26 сентября 2014

Попробовал метод, предложенный 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;

Наслаждайтесь!

6 голосов
/ 20 июля 2012

Если вы хотите повернуть всю метку (включая символы), вы можете сделать это следующим образом:

  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)];
5 голосов
/ 02 ноября 2015

Это еще один способ рисовать вертикальный текст, используя подклассы UILabel.Но это не то, чего хочет этот вопрос.

Objective-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

Пример изображения:

A sample image

Swift

Он может положить на раскадровку, и смотреть результат непосредственно.Как и изображение, его рамка будет содержать вертикальный текст.И текстовые атрибуты, такие как textAlignment, font, тоже работают хорошо.

A vertical text example

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

}

Swift 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)
    }
}
...