Swift boundingRect为playground和实际项目上的相同输入返回不同的值

时间:2017-08-11 05:36:19

标签: swift string swift-playground

我不完全确定为什么boundingRect在某些情况下会返回不正确的值,例如文本结束时的最大宽度。它适用于所有其他情况。

这里的例子。

func snap(_ x: CGFloat) -> CGFloat {
  let scale = UIScreen.main.scale
  return ceil(x * scale) / scale
}

func snap(_ point: CGPoint) -> CGPoint {
  return CGPoint(x: snap(point.x), y: snap(point.y))
}

func snap(_ size: CGSize) -> CGSize {
  return CGSize(width: snap(size.width), height: snap(size.height))
}

func snap(_ rect: CGRect) -> CGRect {
  return CGRect(origin: snap(rect.origin), size: snap(rect.size))
}


extension String {
  func boundingRect(with size: CGSize, attributes: [String: AnyObject]) -> CGRect {
    let options: NSStringDrawingOptions = [.usesLineFragmentOrigin, .usesFontLeading]
    let rect = self.boundingRect(with: size, options: options, attributes: attributes, context: nil)
    return snap(rect)
  }

  func size(fits size: CGSize, font: UIFont, maximumNumberOfLines: Int = 0) -> CGSize {
    let attributes = [NSFontAttributeName: font]
    var size = self.boundingRect(with: size, attributes: attributes).size
    if maximumNumberOfLines > 0 {
      size.height = min(size.height, CGFloat(maximumNumberOfLines) * font.lineHeight)
    }
    return size
  }

  func width(with font: UIFont, maximumNumberOfLines: Int = 0) -> CGFloat {
    let size = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
    return self.size(fits: size, font: font, maximumNumberOfLines: maximumNumberOfLines).width
  }

  func height(fits width: CGFloat, font: UIFont, maximumNumberOfLines: Int = 0) -> CGFloat {
    let size = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
    return self.size(fits: size, font: font, maximumNumberOfLines: maximumNumberOfLines).height
  }

  func height(fits width: CGFloat, attributes: [String:AnyObject]) -> CGFloat {
    let size = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
    return self.boundingRect(with: size, attributes: attributes).height
  }
}

通过以上扩展和方法,我在操场上运行了以下代码。

let str = "ありがとうございます。スマホ専用のページがなくても反映できるかはエンジンにご確認いたします。"
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byWordWrapping
paragraphStyle.alignment = .left
let attributes = [
  NSFontAttributeName: UIFont.systemFont(ofSize: 15),
  NSParagraphStyleAttributeName: paragraphStyle
]
let height = str.height(fits: 320, attributes: attributes)
print("calculated height: ", height)

它返回了54。

然而,当我在简单项目中运行相同的代码(单视图控制器,复制并粘贴到viewDidLoad:中的ViewController时,它返回36(缺少一行高度)。任何想法为什么这两个相同的输入表现不同?

1 个答案:

答案 0 :(得分:0)

我已经在iOS 10.3的多个模拟器上运行了你的代码,他们都给了我54.0的计算高度值。

您没有指定您正在使用的iOS版本,因此这可能很重要。

此外,打印应用程序和游乐场中使用的字体。对于UIFont.systemFont(ofSize:15),我在两者中都得到.SFUIText。