【问题标题】:iOS Drawing text in the centre of shapesiOS 在形状中心绘制文本
【发布时间】:2014-02-11 04:13:29
【问题描述】:

我正在尝试在 iOS 的形状中心绘制文本,例如 Microsoft Office 的插入形状,请参阅:https://www.dropbox.com/s/cgqyyuvy6hcv5g8/Screenshot%202014-01-21%2013.48.17.png

我有一个用于形成形状的坐标数组,可以很好地创建实际形状。

我的第一个策略是遵循这个 stackoverflow 问题:Core Text With Asymmetric Shape on iOS 但是我只能让它在形状底部绘制文本。有什么方法可以让文本垂直和水平居中?

然后我查看了新的 TextKit,但我陷入了如何将 NSTextContainer 子类化以接受 CGPath 或坐标数组来创建要在其中绘制的文本容器的问题。

我的备用解决方案是使用 Core Text 在形状的中心坐标处绘制文本,但这会导致文本在某些形状(例如直角三角形)上绘制在形状之外。

或者,我可以使用任何其他方法在形状的中心获取一些文本吗?

【问题讨论】:

    标签: ios core-graphics core-text textkit


    【解决方案1】:

    这有点棘手。首先,您必须创建一个上下文。 (bounds.size是图片的大小)

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

    然后获取文本的边界框:(font就是你要使用的字体)

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

    将文本绘制到上下文中(x 和 y 标记图像的中心)

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

    获取图片

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    

    结束图像上下文

    UIGraphicsEndImageContext();
    

    我还没有测试过,但这是要走的路。

    【讨论】:

    • 感谢您的建议! - 如果我在一个视图中在 drawRect 的中间绘制多个带有文本的形状,这会起作用吗?
    • 当然会。如果您使用 cgcontextsavecgstate 和 cgcontextrestorecgstate,您可以单独处理每个绘图
    • 抱歉,我想我遗漏了一些东西。为什么你在这个例子中得到了边界框?
    【解决方案2】:

    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())
    

    【讨论】:

      【解决方案3】:

      我从这些答案和相关问题中挑选——没有一个是真正令人满意的——并想出了这个简单的解决方案:

          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()
      

      结果(不管颜色):

      【讨论】:

        【解决方案4】:

        Swift 3 Luca Davanzo 的回答版本

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-12-10
          • 1970-01-01
          • 1970-01-01
          • 2011-10-23
          • 2017-09-12
          • 1970-01-01
          • 1970-01-01
          • 2013-10-17
          相关资源
          最近更新 更多