NSString の UIKit 拡張で文字列を描くやり方

iOSUIView 派生クラスで func draw(_:)override して UIBezierPath やら UIImage やらを描画する横並びで、 文字列も描画するやつの話。

import UIKit すると NSString.draw(at:withAttributes:)NSString.draw(in:withAttributes:) が使える。

NSStringString から as で型変換できる

let string = "Hello"
let nsstring = string as NSString

(10, 10)の位置に文字列を描く(アトリビュートなし)。

let p = CGPoint(x: 10, y: 10)
nsstring.draw(at: p)

ついでに枠線も描いてみる。 NSString.size(withAttributes:) で文字列を描くために必要な領域の高さと幅が得られる。

let size = nsstring.size()
UIColor.red.setStroke()
UIBezierPath(rect: CGRect(origin: p, size: size)).stroke()

f:id:hrt1ro:20180925095849p:plain

ところでなぜだか NSString ではなく Stringインスタンスでも NSString.draw(at:withAttributes:) が呼び出せる様子。

let string = "Hello"
let p = CGPoint(x: 10, y: 10)
string.draw(at: p)  // ←これ
let size = string.size() // ←これも
UIColor.red.setStroke()
UIBezierPath(rect: CGRect(origin: p, size: size)).stroke()

これは、暗黙の型変換がされているのか、何か特別な対応がされているのか、 小一時間調べたくらいじゃわからなかった。 (教えて偉い人)