2012-05-03 11 views
16

私はUISlider(UISliderのサブクラス)を実装しようとしています。これは、親のスライダと同じように振る舞います。私はこれに問題があります。親指幅が通常よりも大きいUISliderハイライト状態

ハイライトされた親の幅は、明らかに通常の親よりも大きくなります(グローが原因)。透明なピクセルパディングを通常の状態イメージに追加して、両方のイメージが同じ幅になるようにすると、通常の状態のサムがトラックの最後に到達しないように見えるという問題があります(最後まで到達しますが、それ以外の場合は表示されます)。

thumbRectForBounds:を使用すると、サムのトラックの先頭部分が正しく整列するようにオフセットすると、もう一方の端で問題が悪化します。

私は両方の画像を必要なだけの幅に保ちます(つまり、通常の状態では余白がなく、2つの画像の幅が同じではありません)。私はUIControl.stateに基づいてthumbRectForBounds:で独立してオフセットを設定できますが、数学の魔法が背後にあるようです。 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; 
} 
+0

http://stackoverflow.com/questions/755510/customizing-uislider-look – VSN

+0

質問は、主にトラック画像であり、サム画像ではありません。自分のスライダーを書くことはまだ唯一の答えかもしれませんが、ネイティブの振る舞いを再現しようとしているので、それをやりなおす必要がないようにする方法があるかどうかは疑問です。 – farski

答えて

1

画像にグロー効果を追加する代わりに、動的に追加する方がよい場合があります。 CALayerを使用してグロー効果を追加することができます。

CALayer

+0

興味深い。私はそれをショット、感謝します。 – farski

+0

UISliderには影を追加できるサブビューやサブレイヤがないようですので、かなり難しくなります。 –

+0

Andreas氏は、サム画像のビューに直接アクセスすることはできないので、これは完全に単純ではありませんが、私はうまくいくと思われる解決策を思いつきました。アイデアをありがとう、Tejesh。 – farski

0

あなたはそれが聞こえるかもしれないが、まだコーディングの数時間を必要とするほど複雑ではありませんあなた自身のスライダーを、ロールができます。

しかし、最も簡単な解決策は、ちょうど同様にカスタムトラック画像を設定することになる。

  1. パディング とカスタム「最小」/「最大」トラック画像右/左側(透明ピクセル)を作成。パディングは、グローの半径から親指の半径(11pt)を差し引いた大きさにする必要があります。
  2. 私は私のアプリケーションのいずれかのカスタムスライダーと同様の問題に出くわし追加パディング
0

の大きさによって、あなたのスライダーの幅を増やしsetMinimumTrackImage:forState:setMaximumTrackImage:forState:

  • であなたのUISliderに画像を適用します。通常のスライダとは異なり、トラックは静的な数値の線ですので、最小と最大のトラック画像を別にする必要はありません。しかし、私は親指のために余分な大きなホットスポットが必要でした。だから私は透明なピクセルの余分なパディングで私の親指のイメージを作って、トラックに透明な画像を割り当てました。目に見えるトラックは、スライダの背後にあるUIImageViewです(実際にはスライダ群の背後にあるUIImageView)。スライダのエッジは、トラック画像のエッジをはるかに超えて延びています。

    私の提案は、UISliderのカスタマイズの限界を打ち砕くのではなく、複数のビューを組み合わせて、意図したスライダを視覚的に構築することです。あなたがトラックを変更することなくできる場合、私の技術を複製することができます。または、スライダが値を変更するたびにカスタムトラックを調整するためにUIViewまたは2つのフレームを操作できます。あなたのアプリでこのスライダーを複数回使用する必要がある場合は、UIViewサブクラスにビューのグループをパッケージ化することができます。スライダーアクションの複雑さによっては、カスタムコントロールを作成する方が慎重な選択になることがあります。

  • 関連する問題