レイヤーなら小数点を指定できる?

投稿者: Anonymous

https://developer.apple.com/design/resources/0.5 を指定しているところがあるので、同じようにできないか? と聞かれ、AutoLayout(厳密にはUIView)では、できない認識だったので、「できないな」と思ったのですが、公式のデザインリソースがそんなことをするのもおかしいと思い、よく見てみると、Inner Shadows の Y に 0.5-0.5が指定されていました。

他にも https://stackoverflow.com/a/37671379/1979953CAGradientLayer を操作していますが、0.5をしている箇所がありました。

CALayerなら小数点を指定してもよいものなのでしょうか?

解決

まずCGRect、CGPoint、CGSizeなどビューの座標系の値に整数でない数値を指定できるかについていうと、指定できます。

相手がUIViewでもCALayerでも関係ありません。意味があるかどうかは別として(後述します)、0.5ポイント単位の座標や長さ、もっと細かい単位の数値を指定することもできます。

次に整数ではない値を指定した場合にどのような効果があるかを説明します。

参考資料としてこちらのドキュメント、またはこちらの回答の図を見ると分かりやすいと思います。

画像の説明をここに入力

上の画像は前者のAppleのドキュメントに載っている図です。

iPhone 4が発売される前は1ポイントが画面の1ピクセルに対応していました。そのとき1ポイントの幅を持つ縦の線を描画することを考えます。

iOSのネイティブの描画システムでは指定した座標が中央に来るように線がひかれます(上記の図の右の例)。

この場合1ポイントを1ピクセルとして描画しようとすると左右のピクセル境界に調整されて2ピクセルの幅の線になってしまいます。合わせて1ピクセルの線を2ピクセルとして描画しているのでアンチエイリアスがかかります。

そうすると、1ピクセルのソリッドな線を描画したい場合には不適切でぼやけた2ピクセルの線が描画されてしまうことになります。
それを避けて、1ピクセルのソリッドな線を描画するにはOriginの座標を0.5ポイント、オフセットすると1ピクセルの幅の線がちょうどピクセル境界に一致するので1ピクセルのソリッドな線が描画されます(上の図の左の例。左端を0としてx方向を2.5ポイントと指定すると(x: 2.5, y: 0, width: 1, height: 5)2.5ポイントの中央を通る1ピクセルの線、が描けます)。

iPhone 4以降のRetina Displayでは1ポイントは2ピクセル以上になるので0.5ポイントのオフセットをしなくてもピクセル境界に合致した線が描画できます。

ただし、今度は物理的な画面で1ピクセルの極細線を描画したい場合に整数値ではできないので、0.5ポイント以下の幅や長さを指定する(DisplayのScaleの値を使って割ることが多い)ことで、1ピクセルの描画が実現できます。

まとめると、ネイティブの描画システムの特性を利用してピクセルの境界に合致してアンチエイリアスを避けたり、1ピクセルの細かい描画をしたい場合に整数ではない値を指定します。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *