【问题标题】:How to calculate the bounding box of a CATextLayer's string?如何计算 CATextLayer 字符串的边界框?
【发布时间】:2012-03-21 06:20:34
【问题描述】:

乍一看,我的问题看起来很简单,但似乎我真的找不到解决方案。 这是什么: 我想计算 CATextLayer 字符串的边界框。 这是我的工作:

CATextLayer *textLayer = [CATextLayer layer];
textLayer.frame = CGRectMake(80, 0.0f, 36.0f, 18.0f);
textLayer.string = @"12";
textLayer.fontSize = [UIFont systemFontSize];
textLayer.foregroundColor = [UIColor whiteColor].CGColor;

NSLog(@"(width,height)=(%f,%f)",
[textLayer.string sizeWithFont:textLayer.font].width,
[textLayer.string sizeWithFont:textLayer.font].height);

问题是输出总是:(width,height) = (8.000000,0.000000)

【问题讨论】:

  • Swift 用户,如果只使用一行(可能更多),请尝试 myCATextLayer.preferredFrameSize() 快速获胜。

标签: iphone objective-c ios cocoa-touch calayer


【解决方案1】:

使用sizeWithFont:constrainedToSize:lineBreakMode:

[someString sizeWithFont:yourFont
       constrainedToSize:CGSizeMake(maxWidthYouSpecify, CGFLOAT_MAX)
           lineBreakMode:UILineBreakModeWordWrap];

【讨论】:

    【解决方案2】:

    从 iOS 7 开始,使用 NSStringboundingRectWithSize:options:attributes:contextsizeWithFont:constrainedToSize:lineBreakMode: 现已弃用。

    CGRect rect = [textLayer.string boundingRectWithSize:textLayer.frame.size options:NSStringDrawingUsesLineFragmentOrigin attributes:nil context:nil];
    CGSize size = CGSizeMake(ceilf(rect.size.width), ceilf(rect.size.height));
    

    【讨论】:

      【解决方案3】:

      //动态CATextLayer使用下面的函数

      func DynamicLableWidth(reason:NSString,cpT:CGPoint,width:CGFloat,reasonLayer:CATextLayer)
      {
      
          //Dynamic CATextLayer with boundingRect
          let font = UIFont(name: "Arial", size: 20)!
          let attributes: [NSString : AnyObject] = [NSFontAttributeName: font]
      
          var rect:CGRect = reason.boundingRectWithSize(reasonLayer.frame.size, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: attributes, context: nil)
      
          var size:CGSize = CGSizeMake(rect.size.width, rect.size.height);
          if cpT.x+20+ceil(size.width)+20>width
          {
              reasonLayer.frame = CGRectMake(cpT.x-20-ceil(size.width)+20,  cpT.y-15, ceil(size.width)+20, 20)
          }
          else
          {
              reasonLayer.frame = CGRectMake(cpT.x+20,  cpT.y-15, rect.size.width+20, 20)
          }
      }
      

      【讨论】:

        【解决方案4】:

        这应该可以解决preferredFrameSize 中的CATextLayer 的问题。代码如下:

        func createSampleLabel(coordinate origin: CGPoint) {
           let textLayer = CATextLayer()
           textLayer.string = "some string \n with line breaks and long values...."
           textLayer.frame = .init(origin: origin, size: textLayer.preferredFrameSize())
        }
        

        【讨论】:

          猜你喜欢
          • 2011-10-22
          • 1970-01-01
          • 2021-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-01
          • 2019-09-05
          相关资源
          最近更新 更多