38 votes

UISlider avec ProgressView combiné

Existe-t-il un moyen fabriqué par Apple House pour obtenir un UISlider avec ProgressView? Ceci est utilisé par de nombreuses applications de streaming, par exemple, quicktimeplayer natif ou youtube. (Juste pour être sûr: je ne suis intéressé que par la visualisation)

Curseur avec chargeur

acclame Simon

47voto

matt Points 60113

Voici une version simple de ce que vous décrivez.

alt text

C'est "simple" dans le sens que je n'ai pas pris la peine d'essayer d'ajouter de l'ombrage et autres subtilités. Mais il est facile à construire et vous pouvez modifier à dessiner d'une manière plus subtile si vous le souhaitez. Par exemple, vous pouvez faire votre propre image et l'utiliser comme le curseur de pouce.

C'est en fait une UISlider sous-classe située au-dessus d'une sous-classe UIView (MyTherm) qui attire le thermomètre, en plus de deux UILabels qui tire les numéros.

Le UISlider sous-classe élimine le haut-piste, de sorte que le thermomètre derrière elle montre à travers. Mais le UISlider pouce (knob) est encore déplaçable de façon normale, et vous pouvez mettre une image personnalisée, obtenir la Valeur événement a Changé lorsque l'utilisateur fait glisser, et ainsi de suite. Voici le code pour le UISlider sous-classe qui élimine sa propre piste:

- (CGRect)trackRectForBounds:(CGRect)bounds {
    CGRect result = [super trackRectForBounds:bounds];
    result.size.height = 0;
    return result;
}

Le thermomètre est une instance d'une coutume sous-classe UIView, MyTherm. J'ai instancié dans la plume et non Opaque et lui a donné une couleur d'arrière-plan de Couleur Claire. Il a un value de la propriété de sorte qu'il sait combien de remplir le thermomètre. Voici son drawRect: code:

- (void)drawRect:(CGRect)rect {
    CGContextRef c = UIGraphicsGetCurrentContext();
    [[UIColor whiteColor] set];
    CGFloat ins = 2.0;
    CGRect r = CGRectInset(self.bounds, ins, ins);
    CGFloat radius = r.size.height / 2.0;
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, CGRectGetMaxX(r) - radius, ins);
    CGPathAddArc(path, NULL, radius+ins, radius+ins, radius, -M_PI/2.0, M_PI/2.0, true);
    CGPathAddArc(path, NULL, CGRectGetMaxX(r) - radius, radius+ins, radius, M_PI/2.0, -M_PI/2.0, true);
    CGPathCloseSubpath(path);
    CGContextAddPath(c, path);
    CGContextSetLineWidth(c, 2);
    CGContextStrokePath(c);
    CGContextAddPath(c, path);
    CGContextClip(c);
    CGContextFillRect(c, CGRectMake(r.origin.x, r.origin.y, r.size.width * self.value, r.size.height));
}

Pour changer le thermomètre de la valeur, modifiez le MyTherm de l'instance de l' value le nombre est compris entre 0 et 1, et dites-lui de se redessiner avec setNeedsDisplay.

20voto

Sam Doshi Points 2656

C'est faisable en utilisant les commandes standard.

Dans Interface Builder placez votre UISlider immédiatement sur le dessus de votre UIProgressView et de les faire de la même taille.

Sur un UISlider l'arrière-plan de la ligne horizontale est appelée la piste, l'astuce est de le rendre invisible. Nous faisons cela avec une image PNG transparente et l' UISlider méthodes setMinimumTrackImage:forState: et setMaximumTrackImage:forState:.

Dans l' viewDidLoad méthode de votre point de vue contrôleur ajouter:

[self.slider setMinimumTrackImage:[UIImage imageNamed:@"transparent.png"] forState:UIControlStateNormal];
[self.slider setMaximumTrackImage:[UIImage imageNamed:@"transparent.png"] forState:UIControlStateNormal];

self.slider se réfère à votre UISlider.

J'ai testé le code dans Xcode, et cela vous donnera un curseur indépendante avec une barre de progression.

4voto

Emile Khattar Points 309

Créez un UISlider:

 // 1
// Make the slider as a public propriety so you can access it
playerSlider = [[UISlider alloc] init];
[playerSlider setContinuous:YES];
[playerSlider setHighlighted:YES];
// remove the slider filling default blue color
[playerSlider setMaximumTrackTintColor:[UIColor clearColor]];
[playerSlider setMinimumTrackTintColor:[UIColor clearColor]];
// Chose your frame
playerSlider.frame = CGRectMake(--- , -- , yourSliderWith , ----);

// 2
// create a UIView that u can access and make it the shadow of your slider 
shadowSlider = [[UIView alloc] init];
shadowSlider.backgroundColor = [UIColor lightTextColor];
shadowSlider.frame = CGRectMake(playerSlider.frame.origin.x , playerSlider.frame.origin.y , playerSlider.frame.size.width , playerSlider.frame.origin.size.height);
shadowSlider.layer.cornerRadius = 4;
shadowSlider.layer.masksToBounds = YES;
[playerSlider addSubview:shadowSlider];
[playerSlider sendSubviewToBack:shadowSlider];


// 3
// Add a timer Update your slider and shadow slider programatically 
 [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES];


-(void)updateSlider {

// Update the slider about the music time
playerSlider.value = audioPlayer.currentTime; // based on ur case 
playerSlider.maximumValue = audioPlayer.duration;

float smartWidth = 0.0;
smartWidth = (yourSliderFullWidth * audioPlayer.duration ) / 100;
shadowSlider.frame = CGRectMake( shadowSlider.frame.origin.x , shadowSlider.frame.origin.y , smartWidth , shadowSlider.frame.size.height);
 

}

Prendre plaisir! PS: je pourrais avoir des fautes de frappe

3voto

not really Jake Points 3440

Idée 1: Vous pouvez facilement utiliser la UISlider comme un progrès vue par sous-classement. Il répond à des méthodes telles que l'setValue:animation: "avec laquelle vous pouvez définir la valeur (j'.e: le progrès) de la vue.

Votre seule "restriction" de la création de ce que vous voyez dans votre exemple, le tampon de la barre, que vous pouvez créer par 'créative' le dépouillement de la UISlider (parce que vous pouvez ajouter des skins personnalisés pour elle), et peut-être définir que la peau de la programmation.

Idée 2: L'autre (plus facile) l'option est à la sous-classe UIProgressView, et de créer un UISlider à l'intérieur de cette sous-classe. Vous pouvez la peau de la UISlider d'avoir un voir-à travers la peau (pas de bar, juste le bouton visible) et le poser sur le UIProgressView.

Vous pouvez utiliser le UIProgressView pour le pré-chargement (tampon) et le UISlider pour film de contrôle et les progrès de l'indication.

Semble assez facile :-)

Edit: effectivement répondre à votre question, il n'y a pas de maison, mais il serait facile de le faire avec les outils mis à disposition.

1voto

John Points 11

Vous pouvez faire un truc comme ça, c'est plus facile et plus compréhensif. Insérez simplement le code ci-dessous dans votre sous-classe UISlider.

 - (void)layoutSubviews
{
    [super layoutSubviews];

    if (_availableDurationImageView == nil) {
        // step 1 
        // get max length that our "availableDurationImageView" will show
        UIView *maxTrackView = [self.subviews objectAtIndex:self.subviews.count - 3];
        UIImageView *maxTrackImageView = [maxTrackView.subviews objectAtIndex:0];
        _maxLength = maxTrackImageView.width;

        // step 2
        // get the right frame where our "availableDurationImageView" will place in       superView
        UIView *minTrackView = [self.subviews objectAtIndex:self.subviews.count - 2];
        _availableDurationImageView = [[UIImageView alloc] initWithImage:[[UIImage     imageNamed:@"MediaSlider.bundle/4_jindu_huancun.png"]     resizableImageWithCapInsets:UIEdgeInsetsMake(0, 2, 0, 2)]];
        _availableDurationImageView.opaque = NO;
        _availableDurationImageView.frame = minTrackView.frame;

        [self insertSubview:_availableDurationImageView belowSubview:minTrackView];
    }
}


- (void)setAvailableValue:(NSTimeInterval)availableValue
{
    if (availableValue >=0 && availableValue <= 1) {
        // use "maxLength" and percentage to set our "availableDurationImageView" 's length
        _availableDurationImageView.width = _maxLength * availableValue;
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X