web-dev-qa-db-ja.com

UISliderの親指の画像の中心を取得する方法

いくつかのインターフェースのアイデアをテストするために、カスタムISliderを作成しています。主に親指の画像を大きくすることに基づいています。

私はそれを行う方法を見つけました、のように:

UIImage *thumb = [UIImage imageNamed:@"newThumbImage_64px.png"];  
[self.slider setThumbImage:thumb forState:UIControlStateNormal];  
[self.slider setThumbImage:thumb forState:UIControlStateHighlighted];  
[thumb release];  

関連する値を計算するには、親指の画像を操作しているときに、親指の画像の中心点がどこにあるかを知る必要があります。そして、ポイントはそのスーパービューの座標にある必要があります。

ISliderのドキュメントを見ると、これを追跡するプロパティは見つかりませんでした。

これを計算する簡単な方法はありますか、それとも既存の値から導き出すことができますか?

30
willc2

これにより、ビュー座標でUISliderの親指の中心の画像の正しいX位置が返されます。

- (float)xPositionFromSliderValue:(UISlider *)aSlider {
     float sliderRange = aSlider.frame.size.width - aSlider.currentThumbImage.size.width;
     float sliderOrigin = aSlider.frame.Origin.x + (aSlider.currentThumbImage.size.width / 2.0);

     float sliderValueToPixels = (((aSlider.value - aSlider.minimumValue)/(aSlider.maximumValue - aSlider.minimumValue)) * sliderRange) + sliderOrigin;

     return sliderValueToPixels;
}

ビューコントローラに配置し、次のように使用します:(スライダーという名前のプロパティを想定)

float x = [self xPositionFromSliderValue:self.slider];
57
willc2

上記の提案を読んだ後、これを試しました-

yourLabel = [[UILabel alloc]initWithFrame:....];

//Call this method on Slider value change event

-(void)sliderValueChanged{
    CGRect trackRect = [self.slider trackRectForBounds:self.slider.bounds];
    CGRect thumbRect = [self.slider thumbRectForBounds:self.slider.bounds
                               trackRect:trackRect
                                   value:self.slider.value];

    yourLabel.center = CGPointMake(thumbRect.Origin.x + self.slider.frame.Origin.x,  self.slider.frame.Origin.y - 20);
}

Swiftバージョンの場合

func sliderValueChanged() -> Void {
        let trackRect =  self.slider.trackRect(forBounds: self.slider.bounds)
        let thumbRect = self.slider.thumbRect(forBounds: self.slider.bounds, trackRect: trackRect, value: self.slider.value)
        yourLabel.center = CGPoint(x: thumbRect.Origin.x + self.slider.frame.Origin.x + 30, y: self.slider.frame.Origin.y - 60)
    }

このスニペットを使用すると、最も正確な値を取得できます。

22
girish_vr

スウィフト3

extension UISlider {
    var thumbCenterX: CGFloat {
        let trackRect = self.trackRect(forBounds: frame)
        let thumbRect = self.thumbRect(forBounds: bounds, trackRect: trackRect, value: value)
        return thumbRect.midX
    }
}
18
Med Abida

なぜあなた方の誰もがマニュアルを読むことからなる最も簡単な答えを提供しないのか知りたいです。次の方法を使用するだけで、これらすべての値を正確に計算し、それらがそのようにとどまるようにすることもできます。

- (CGRect)trackRectForBounds:(CGRect)bounds
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value

これは、開発者向けドキュメントで簡単に見つけることができます。

親指の画像が変更され、その配置方法を変更したい場合は、これらのメソッドをサブクラス化してオーバーライドします。最初のものは、親指が2番目のものを親指自体の位置に移動できる長方形を提供します。

11
Psycho

代わりに-[UIView convertRect:fromView:]メソッドを使用することをお勧めします。複雑な計算をしなくても、よりクリーンで簡単です。

- (IBAction)scrub:(UISlider *)sender
{
    CGRect _thumbRect = [sender thumbRectForBounds:sender.bounds
                                        trackRect:[sender trackRectForBounds:sender.bounds]
                                            value:sender.value];
    CGRect thumbRect = [self.view convertRect:_thumbRect fromView:sender];

    // Use the rect to display a popover (pre iOS 8 code)
    [self.popover dismissPopoverAnimated:NO];
    self.popover = [[UIPopoverController alloc] initWithContentViewController:[UIViewController new]];
    [self.popover presentPopoverFromRect:thumbRect inView:self.view
                permittedArrowDirections:UIPopoverArrowDirectionDown|UIPopoverArrowDirectionUp animated:YES];
}
10
Yariv Nissim

最初にUISliderの値の間隔をパーセントでマッピングし、次にスライダーのサイズの同じパーセントから親指のサイズのパーセントを引いた値を取得することでアプローチしました。この値に親指のサイズの半分を加算して、中心を取得しました。

    - (float)mapValueInIntervalInPercents: (float)value min: (float)minimum max: (float)maximum
    {
        return (100 / (maximum - minimum)) * value -
               (100 * minimum)/(maximum - minimum);
    }    


    - (float)xPositionFromSliderValue:(UISlider *)aSlider
    {
        float percent = [self mapValueInIntervalInPercents: aSlider.value
                              min: aSlider.minimumValue
                              max: aSlider.maximumValue] / 100.0;

        return percent * aSlider.frame.size.width -
               percent * aSlider.currentThumbImage.size.width +
               aSlider.currentThumbImage.size.width / 2;
    }
6
luvieere

Swift 3.
よろしければご参照ください。

import UIKit

extension UISlider {

    var trackBounds: CGRect {
        return trackRect(forBounds: bounds)
    }

    var trackFrame: CGRect {
        guard let superView = superview else { return CGRect.zero }
        return self.convert(trackBounds, to: superView)
    }

    var thumbBounds: CGRect {
        return thumbRect(forBounds: frame, trackRect: trackBounds, value: value)
    }

    var thumbFrame: CGRect {
        return thumbRect(forBounds: bounds, trackRect: trackFrame, value: value)
    }
}
2
木耳ちゃん

IBと1px幅の親指の画像で少し遊んだ後、親指の位置はまさにあなたが期待する場所です。

UIImage       *thumb = [UIImage imageNamed:@"newThumbImage_64px.png"];  
CGRect        sliderFrame = self.slider.frame;
CGFloat       x = sliderFrame.Origin.x + slideFrame.size.width * slider.value + thumb.size.width / 2;
CGFloat       y = sliderFrame.Origin.y + sliderFrame.size.height / 2;

return CGPointMake(x, y);
2
Ben Gottlieb

これがSwift 2.2ソリューションです。拡張機能を作成しました。これは、デフォルトのイメージでのみ試しました。

import UIKit

extension UISlider {

    var thumbImageCenterX: CGFloat {
        let trackRect = trackRectForBounds(bounds)
        let thumbRect = thumbRectForBounds(bounds, trackRect: trackRect, value: value)

        return thumbRect.Origin.x + thumbRect.width / 2 - frame.size.width / 2
    }
}
1
Ovi Bortas

これは、UISliderが画面上の任意の場所に配置されている場合に機能します。他のほとんどのソリューションは、UISliderが画面の左端に位置合わせされている場合にのみ機能します。これを実現するために、thumbRectにframeではなくboundsを使用したことに注意してください。そして、trackRectにframeまたはboundsを使用することに基づいて、2つのバリエーションを示します。

extension UISlider {

    //this version will return the x coordinate in relation to the UISlider frame
    var thumbCenterX: CGFloat {
        return thumbRect(forBounds: frame, trackRect: trackRect(forBounds: bounds), value: value).midX
    }

    //this version will return the x coordinate in relation to the UISlider's containing view
    var thumbCenterX: CGFloat {
        return thumbRect(forBounds: frame, trackRect: trackRect(forBounds: frame), value: value).midX
    }

}
0
Harris

上記のソリューションは、UISliderが水平の場合に役立ちます。最近のプロジェクトでは、角度のあるUISliderを使用する必要があります。したがって、xとyの両方の位置を取得する必要があります。以下を使用してx、y軸を計算します。

- (CGPoint)xyPositionFromSliderValue:(UISlider *)aSlider WithAngle:(double)aangle{
   //aangle means the dextrorotation angle compare to horizontal.
   float xOrigin = 0.0;
   float yOrigin = 0.0;
   float xValueToaXis=0.0;
   float yValueToaXis=0.0;
   float sliderRange = slider_width-aSlider.currentThumbImage.size.width;
   xOrigin = aSlider.frame.Origin.x+slider_width*fabs(cos(aangle/180.0*M_PI));
   yOrigin = aSlider.frame.Origin.y;

   xValueToaXis = xOrigin + ((((((aSlider.value-aSlider.minimumValue)/(aSlider.maximumValue-aSlider.minimumValue)) * sliderRange))+(aSlider.currentThumbImage.size.width / 2.0))*cos(aangle/180.0*M_PI)) ;
   yValueToaXis =  yOrigin + ((((((aSlider.value-aSlider.minimumValue)/(aSlider.maximumValue-aSlider.minimumValue)) * sliderRange))+(aSlider.currentThumbImage.size.width / 2.0))*sin(aangle/180.0*M_PI));

   CGPoint xyPoint=CGPointMake(xValueToaXis, yValueToaXis);
   return xyPoint;
}

また、UISliderをベースにレンジャースライダーを作成できますか?ありがとう。

0
Ding