开发者

How does iOS's UISlider evaluate the position it's on?

Is it linearly or logarithmically? I ask because I'm taking a Mobile Apps directed study and we're using Sam's Teach Yourself iPhone (2nd Edition, also, booooooo!). In Hour 8, if anyone has it, we make an animation, and we use a slider to determine how long it takes the animation to loop through. We're then supposed to make a manual entry option for how many loops per second. I have both of those implemented and have the slider change to what the manual entry was, but the only problem I can see is that when I enter a value in manually, it will cycle through the correct amount of loops and move the slider to the correct positioning, but whenever I set the speed of animation with the slider it seems to evaluate the values logarithmically instead of linearly. I have a range of .05 - 19.95 for the slider, so it starts at .05 and doesn't get passed the value '1' until like 4/5 of the way through, then it's from 1-20 the rest of the way and you pretty much have no accuracy on which number you get.

Thanks for your time, if you need me to rephrase something let me know!


*Revision


Okay, here we go.

ImageHopViewController.h:

#import <UIKit/UIKit.h>

@interface ImageHopViewController : UIViewController {
    IBOutlet UIImageView *images;
    IBOutlet UILabel *hps;
    IBOutlet UISlider *slider;
    IBOutlet UIButton *toggle;
    IBOutlet UITextField *manual;
    IBOutlet UIButton *go;
}

@property(retain, nonatomic) UIImageView *images;
@property(retain, nonatomic) UILabel *hps;
@property(retain, nonatomic) UISlider *slider;
@property(retain, nonatomic) UIButton *toggle;
@property(retain, nonatomic) UITextField *manual;
@property(retain, nonatomic) UIButton *go;

-(IBAction)toggleAnimation:(id)sender;
-(IBAction)setSpeed:(id)sender;
-(IBAction)manualEntry:(id)sender;

@end

ImageHopViewController.m:

#import "ImageHopViewController.h"

#import "ImageHopViewController.h"

@implementation ImageHopViewController

@synthesize images;
@synthesize hps;
@synthesize slider;
@synthesize toggle;
@synthesize manual;
@synthesize go;

-(IBAction)toggleAnimation:(id)sender{
    if(images.isAnimating) {
        [images stopAnimating];
        [toggle setTitle:@"Begin!" forState:UIControlStateNormal];
    }else{
        [images startAnimating];
        [toggle setTitle:@"Desist!" forState:UIControlStateNormal];
    }
}

-(IBAction)setSpeed:(id)sender {
    NSString *hopRate;
    images.animationDuration=20-slider.value;
    [images startAnimating];
    [toggle setTitle:@"Desist!" forState:UIControlStateNormal];
    hopRate=[[NSString alloc] initWithFormat:@"%1.2f", 1/(20-slider.value)];
    hps.text=hopRate;
    [hopRate release];
}

-(IBAction)manualEntry:(id)sender{
    NSString *hopRate;
    NSString *manualValue;
    float value;
    manualValue=manual.text;
    value=[manualValue floatValue];
    slider.value=value;
    images.animationDuration=1/slider.value;
    [images startAnimating];
    [toggle setTitle:@"Desist!" forState:UIControlStateNormal];
    hopRate=[[NSString alloc] initWithFormat:@"%1.2f", 1/(20-slider.value)];
    hps.text=manualValue;
    [hopRate release];
}

- (void)dealloc
{
    [images dealloc];
    [hps dealloc];
    [slider dealloc];
    [toggle dealloc];
    [manual dealloc];
    [go dealloc];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{    
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

- (void)viewDidLoad
{
    NSA开发者_运维知识库rray *animation;
    animation=[[NSArray alloc] initWithObjects:
               [UIImage imageNamed:@"frame-1.png"],
               [UIImage imageNamed:@"frame-2.png"],
               [UIImage imageNamed:@"frame-3.png"],
               [UIImage imageNamed:@"frame-4.png"],
               [UIImage imageNamed:@"frame-5.png"],
               [UIImage imageNamed:@"frame-6.png"],
               [UIImage imageNamed:@"frame-7.png"],
               [UIImage imageNamed:@"frame-8.png"],
               [UIImage imageNamed:@"frame-9.png"],
               [UIImage imageNamed:@"frame-10.png"],
               [UIImage imageNamed:@"frame-11.png"],
               [UIImage imageNamed:@"frame-12.png"],
               [UIImage imageNamed:@"frame-13.png"],
               [UIImage imageNamed:@"frame-14.png"],
               [UIImage imageNamed:@"frame-15.png"],
               [UIImage imageNamed:@"frame-16.png"],
               [UIImage imageNamed:@"frame-17.png"],
               [UIImage imageNamed:@"frame-18.png"],
               [UIImage imageNamed:@"frame-19.png"],
               [UIImage imageNamed:@"frame-20.png"],
               nil
               ];
    images.animationImages=animation;
    images.animationDuration=10;
    [animation release];
    [super viewDidLoad];
}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
    // Return YES for supported orientations
    return YES;
}

@end

The NIB file just has a UIImageView (images), a UISlider (slider) for the animation speed, a UILabel (hps) for displaying the "hops per second", a UIButton (toggle) to toggle the animation, a UITextField (manual) for manual entry and another UIButton (go) to start the animation with the entered text converted to float.

Since I have (id) for the object type that's being received, would that affect it in anyway? I'm still new to this so how would I go about remedying this?


The UISlider is linear between its minimumValue (left) and maximumValue (right).

You may want to check the continuous property to see if that isn't the culprit:

continuous

Contains a Boolean value indicating whether changes in the sliders value generate continuous update events.

@property(nonatomic, getter=isContinuous) BOOL continuous

Discussion

If YES, the slider sends update events continuously to the associated target’s action method. If NO, the slider only sends an action event when the user releases the slider’s thumb control to set the final value.

The default value of this property is YES.


UISlider is definitely linear. A quick NSLog in action method should show this (NSLog(@"Slider value %f", sender.value);).

Offhand, I would say your issue is probably with type casting (unintentionally converting your float to an int somewhere). I'd have to see code to confirm or deny that tho.



*Solution


Okay, the animationDuration inside setSpeed needed to be changed to images.animationDuration=1/slider.value; and the float inserted into hopRate in setSpeed needed to be changed to just slider.value instead of 1/(20-slider.value)];.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜