カスタムUISlider(UISliderのサブクラス)を実装しようとしています。これは、強調表示されたときに親指の周りが光るネイティブスライダーと同じように動作します。しかし、私はこれに問題があります。
ハイライトされた親指の(有効な)幅は、通常の親指よりも明らかに大きくなっています(グローのため)。通常の状態の画像に透明なピクセルパディングを追加して、両方の画像の幅が同じになるようにすると、問題は、通常の状態のサムがトラックの最後に到達したようには見えないことです(ただし、パディングによりそれ以外の場合は表示されます)。
thumbRectForBounds:を使用して、親指をオフセットしてトラックの先頭に正しく合わせると、もう一方の端で問題が悪化するだけです。
両方の画像を必要な幅だけに保つと(つまり、通常の状態ではパディングがなく、2つは同じ幅ではありません)、近づきました。オフセットはthumbRectForBoundsで個別に設定できます:UIControl.stateに基づいていますが、舞台裏で数学の魔法が行われているようです。UISliderが両方の状態の画像が完全に並んでいると考える唯一の場所は、正確な中心です。
トラックに沿った相対位置に基づいてハイライト状態のオフセットを決定する数学を実装する必要があるようです。中央にゼロのyオフセットが必要になります(UISliderは両方の画像を中央に配置します。つまり、画像は整列します)。極端な場合は、グローを完全に補うyオフセットが必要になります。そしてその間に、yオフセットを補間する必要があります。
これは、ネイティブスライダーが行うことを再現するための多くの作業のように思われるので、おそらく私は明らかな何かを見逃しています。
現在のソリューションを更新する:
追加されるグローのサイズについていくつかの仮定を行うため、完全に移植可能ではありません。CALayerに直接描画するのではなく、画像を使用してグローを追加しています。これがどれほどパフォーマンスが良いかはまだテストしていません。
基本的に、デフォルトの状態の親指の画像の高さを寸法とする正方形のレイヤーを作成し、それを親指の中央に配置してから、グローを描画します(グローのみで、グローのある親指の個別のイメージではありません。ハイライト状態の画像を使用して)をレイヤーに追加します。
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {
CGRect r = [super thumbRectForBounds:bounds trackRect:rect value:value];
[thumbHighlightOverlayLayer removeFromSuperlayer];
thumbHighlightOverlayLayer = [CALayer layer];
int x = r.origin.x + (r.size.width / 2) - (r.size.height / 2);
thumbHighlightOverlayLayer.frame = CGRectMake(x, r.origin.y, r.size.height, r.size.height);
UIImage* thumbHighlightOverlayImage = [UIImage imageNamed:@"thumb-highlight"];
thumbHighlightOverlayLayer.contents = (id)thumbHighlightOverlayImage.CGImage;
switch (self.state) {
case UIControlStateHighlighted:
[[self layer] addSublayer:thumbHighlightOverlayLayer];
break;
default:
break;
}
return r;
}