@matt is correctあなたのレイヤのcontentsScale
を変更することについて - これはあなたがここで直面している問題ではないようです。
レイヤのcontentsScale
は、レイヤがレンダリングされる「論理」ピクセルのバッキングストアのサイズにのみ影響します。しかし、物理的なスクリーン上に表示されるために、このバッキングストアは、実際のデバイスの物理座標系と一致するように、ダウンサンプリングまたはアップサンプリングされる。
「論理」ピクセルの1倍コンテンツスケーリングされたバッキングストアに1ptの線を描画すると、その座標系の1px線として表されます。ただし、2xディスプレイに表示するにはアップサンプリングする必要があります。これは効果的に2倍の幅になります(ただし、アップサンプリングの性質は品質が低下することを意味します)。
倍精度浮動小数点型ストアで1ptの線を描画すると、その座標系で2px線として表されます。バッキング座標系&の物理座標系が一致するので、サンプリングする必要はなく、2xディスプレイに2px線として表示されます。
したがって、contentsScale
は、実際には、フィジカルのピクセル比率には影響しません。品質にのみ影響します(サンプリングのため)。したがって、サンプリングによる品質の低下を避けるために、デバイスのディスプレイの物理的なスケールと "論理"ピクセルのバッキング表示のスケールを一致させる必要があるため、contentsScale
の画面のスケールを使用する必要があります。ただし、線幅に1.0
を使用すると、線幅がポイントで定義されているので、contentsScale
にかかわらず、2xディスプレイでは2px線、3xディスプレイでは3px線が生成されます。線幅をピクセル単位で測定したい場合は、画面の縮尺で分割する必要があります。
あなたの疑問を持っているように見える問題は、あなたが1ピクセルの線幅と線を引くしているということです、しかしあなたは(ダッシュパターンの線長さため1PTを設定しています)。したがって、2xのディスプレイでは、各セグメントが2x1ピクセルを占めるラインにつながります。
解決策は、のラインダッシュパターンと同様に、lineWidth
のを指定することです。たとえば:
shapelayer.lineDashPattern = [1.0/UIScreen.mainScreen().scale, 3] // set whatever you want for the unstroked line dash length
shapelayer.lineWidth = 1.0/UIScreen.mainScreen().scale
さらに、あなたがクリップしたいピクセルに応じて、2倍のディスプレイ上の1倍または3倍の表示、および0.25ポイント(0.75ポイントで0.5ポイント、あなたのパスをオフセットする必要がありますとの行)。このオフセットは、水平の場合はラインのy座標に、垂直の場合はx座標に適用するとよいでしょう。これは、ラインのストロークがラインに「鞍を打つ」ことを意味します。つまり、ラインの両側に描画されます。ラインの位置に整数を使用すると、ピクセル境界上にそれを描画します。
通常、ポイントを使用するときに大きな影響はありませんが、ピクセルレベルで描画する場合は重要です。ラインをオフセットするとピクセルの中心に揃えられます。つまり、ストロークは1ピクセルだけを占めます。 1ピクセルのラインがピクセル中心に正しく配置されていないと、2ピクセルに渡って輝度が低下して表示され、望ましくない効果が生じます。
ストロークがラインをサドルするので、直線のピクセル行の中心線上にあることを常に確認する必要があります。おそらく、1xまたは3xディスプレイの場合は0.5ポイント、2xディスプレイの場合は0.25ポイントでオフセットする必要があります。また、「contentsScale」を設定することは、マットが指摘するように良い考えです;) – Hamish
ピクセルをポイントと混同しないでください。あなたは1つの_point_行を要求しており、あなたはそれを取得しています。あなたが得ているのは、2ピクセルレンダリングです。 – matt