LoginSignup
171
80

More than 3 years have passed since last update.

なぜiPhone 11 Pro では0.5の線が描画できないのか調べてみた

Last updated at Posted at 2020-02-04

環境

  • Xcode 11.3

何が起こったのか

いつもどおり 0.5 の線を引くために Storyboard の AutoLayout で Height = 0.5 の制約を指定した。

image.png

すると、デザイナーから「線の太さにばらつきがあるので揃えてほしい」と指摘があった。

image.png

↑たしかによく見ると上の線のほうが若干濃くも見える・・。両方とも 0.5 で指定しているが、念のため次のコードを書いて height を出力してみた。

print(separator1.frame.size.height) // 上の線
print(separator2.frame.size.height) // 下の線

すると、

0.66666666666666
0.33333333333333

と出力された!

目の錯覚ではなく、たしかに上の線のほうが濃いことがわかった。

なぜ0.5で指定しているのに正しく描画されないか

Twitter にてこの疑問をつぶやいてみたところ、 @kishikawakatsumi さんが回答をくださった。

Frameの小数部分は実行時にPixel alignedになるように丸められるからですね。Scaleをかけて割る、みたいな処理が自動的に入ってます。
https://twitter.com/k_katsumi/status/1224279359529205760

なるほど!

つまり、iPhone 11 Pro のような x3 でレンダリングされるデバイスは 1pt の線が実際には 3px で描画される。pxに小数を含むことはできないため、小数点以下は丸められてしまう。

例)0.5pt で指定された線は1.5pxで描画しようとするが、小数点が丸められ、1px(=0.3333pt)か2px(=0.6666pt)として描画される。

このとき、どう丸められるかはコントロールできない。 このため、太さに差が出てしまっていた!

参考:x2 や x3 についてはこのデバイス一覧表がわかりやすい
https://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

どうしたらよいか

やはり同じ悩みを持っている人がいた。
ios - How to create a line width of 0.5 pixels - Stack Overflow

つまり、

  • x3 デバイスでは 0.3 pt で指定するようにする
  • x2 デバイスでは 0.5 pt で指定するようにする

このようにすると、確かにどのデバイスでもばらつきがなく線画描画されるようになった。

しかし、 Storyboard では 0.5 単位でしか height を指定できなので、次のようなコードを書いて線を実装する必要がありそう。

(1.0 / [UIScreen mainScreen].scale)

2020/2/4 追記:
1 / scaleの高さを制約に設定したSeparatorというCustom Viewを作る方法もあるそうです!@IBDesignable
にしておくとStoryboardに置くだけで使える
https://twitter.com/k_katsumi/status/1224503484822671360


なにかおかしなことを書いていたらコメントお願いします :pray:

171
80
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
171
80