iOS Рисование текста в центре фигур

Я пытаюсь нарисовать текст в центре фигур в iOS, примером может быть форма вставки Microsoft Office, см. https://www.dropbox.com/s/cgqyyuvy6hcv5g8/Screenshot%202014-01-21%2013.48.17.png

У меня есть массив координат, который используется для формирования формы, который отлично подходит для создания фактической формы.

Моя первая тактика заключалась в следующем: Основной текст с асимметричной формой на iOS однако я могу заставить его рисовать текст только внизу фигуры. Есть ли способ центрировать текст по вертикали и горизонтали?

Затем я взглянул на новый TextKit, но я застрял в том, как создать подкласс NSTextContainer, чтобы принять либо CGPath, либо массив координат для создания текстового контейнера для рисования внутри.

Мое решение для резервного копирования - использовать Core Text для рисования текста в центральной координате фигуры, однако это приведет к тому, что текст будет отображаться за пределами фигуры на некоторых фигурах, таких как прямоугольный треугольник.

В качестве альтернативы, есть ли какие-либо другие методы, которые я мог бы использовать, чтобы поместить текст немного в центре фигуры?

Спасибо,

Даниэль.


person Danielle    schedule 21.01.2014    source источник


Ответы (4)


Я сделал выбор из этих ответов и связанных с ними вопросов - ни один из них не был по-настоящему удовлетворительным - и пришел к такому простому решению:

    UIGraphicsBeginImageContext(CGSize.init(width: imageWidth, height: imageHeight))

    let string = "ABC" as NSString

    let attributes = [
            NSFontAttributeName : UIFont.systemFontOfSize(40),
            NSForegroundColorAttributeName : UIColor.redColor()
        ]

    // Get the width and height that the text will occupy.
    let stringSize = string.sizeWithAttributes(attributes)

    // Center a rect inside of the image
    // by going half the difference to the right and down.
    string.drawInRect(
        CGRectMake(
            (imageWidth - stringSize.width) / 2,
            (imageHeight - stringSize.height) / 2,
            stringSize.width,
            stringSize.height
        ),
        withAttributes: attributes
    )

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

Результат (не говоря уже о цветах):

Строка ABC по центру изображения

person easytarget    schedule 23.02.2016

Swift 3 версия ответа Луки Даванцо

struct UIUtility {

static func imageWithColor(color: UIColor, circular: Bool) -> UIImage? {
    let size: CGFloat = circular ? 100 : 1;
    let rect = CGRect(x: 0.0, y: 0.0, width: size, height: size)
    UIGraphicsBeginImageContext(rect.size)
    if let context = UIGraphicsGetCurrentContext() {
        context.setFillColor(color.cgColor)
        if(circular) {
            context.fillEllipse(in: rect)
        }
        else {
            context.fill(rect)
        }
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    return nil
}

static func drawText(text: NSString, font: UIFont, image: UIImage, point: CGPoint, textColor: UIColor = UIColor.white) -> UIImage? {
    UIGraphicsBeginImageContext(image.size)
    image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
    let rect = CGRect(x: point.x, y: point.y, width: image.size.width, height: image.size.height)
    text.draw(in: rect.integral, withAttributes: [ NSFontAttributeName: font, NSForegroundColorAttributeName: textColor ])
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

static func circleImageWithText(text: String, font: UIFont, circleColor: UIColor, textColor: UIColor = UIColor.white) -> UIImage? {
    if let image = UIUtility.imageWithColor(color: circleColor, circular: true) {
        let textSize = NSString(string: text).size(attributes: [ NSFontAttributeName: font])
        let centerX = ((image.size.width) / 2.0) - (textSize.width / 2.0)
        let centerY = ((image.size.height) / 2.0) - (textSize.height / 2.0)
        let middlePoint = CGPoint(x: centerX, y: centerY)
        return UIUtility.drawText(text: text as NSString, font: font, image: image, point: middlePoint, textColor: textColor)
    }
    return nil
}
}
person Mario Steingruber    schedule 29.03.2017

Это немного сложно. Сначала вам нужно создать контекст. (bounds.size - размер изображения)

UIGraphicsBeginImageContext(bounds.size); 
CGContextRef context = UIGraphicsGetCurrentContext();

Затем получите ограничивающую рамку текста: (шрифт - это шрифт, который вы хотите использовать)

CGSize textSize =
[yourText sizeWithAttributes:@{NSFontAttributeName:font}];

нарисуйте текст в контексте (x и y обозначают центр изображения)

[yourText drawAtPoint:CGPointMake(x, y) withAttributes:@{NSFontAttributeName:font}];

Получите изображение

UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 

Конечный контекст изображения

UIGraphicsEndImageContext();

Я не тестировал это, но это способ.

person Zoltan Varadi    schedule 21.01.2014
comment
Спасибо за идею! - будет ли это работать, если я рисую несколько фигур с текстом посередине в drawRect в одном представлении? - person Danielle; 23.01.2014
comment
Конечно, будет. Вы можете обрабатывать каждый рисунок отдельно, если используете cgcontextsavecgstate и cgcontextrestorecgstate - person Zoltan Varadi; 01.02.2014
comment
извините, я что-то упускаю. Почему в этом примере вы получили ограничивающую рамку? - person Sean Danzeiser; 03.10.2014

Swift 2.0 совместим.

Моей целью было нарисовать круг с центрированным текстом внутри.

struct UIUtility {

  static func imageWithColor(color: UIColor, circular : Bool) -> UIImage {
    let size : CGFloat = circular ? 100 : 1;
    let rect = CGRectMake(0.0, 0.0, size, size)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()
    CGContextSetFillColorWithColor(context, color.CGColor)
    if(circular) {
        CGContextFillEllipseInRect(context, rect)
    }
    else {
        CGContextFillRect(context, rect)
    }
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
  }

  static func drawText(text: NSString, font: UIFont, image: UIImage, point: CGPoint, textColor: UIColor = UIColor.whiteColor()) -> UIImage {
    UIGraphicsBeginImageContext(image.size)
    image.drawInRect(CGRectMake(0, 0, image.size.width, image.size.height))
    let rect = CGRectMake(point.x, point.y, image.size.width, image.size.height)
    text.drawInRect(CGRectIntegral(rect), withAttributes: [ NSFontAttributeName: font, NSForegroundColorAttributeName : textColor ])
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
  }

  static func circleImageWithText(text text: String, font: UIFont, circleColor: UIColor, textColor: UIColor = UIColor.whiteColor()) -> UIImage {
    let image = UIUtility.imageWithColor(circleColor, circular: true)
    let textSize = NSString(string: text).sizeWithAttributes([ NSFontAttributeName: font])
    let centerX = (image.size.width / 2.0) - (textSize.width / 2.0)
    let centerY = (image.size.height / 2.0) - (textSize.height / 2.0)
    let middlePoint = CGPointMake(centerX, centerY)
    return UIUtility.drawText(text, font: font, image: image, point: middlePoint)
  }

}

С помощью этой утилиты мы можем легко создать изображение следующим образом:

let font = UIFont()
let image = UIUtility.circleImageWithText(text: "Center text", font: font, circleColor: UIColor.blackColor())
person Luca Davanzo    schedule 22.10.2015