Setting interval value for UISlider - iphone

I need to set the interval value for an UISlider.
Please help..

yourSlider.value = x;
You should really read the documentation, lots of great resources in the iOS Developer Center.
Edit: With regards to your more specific question in the comments:
yourSlider.minimumValue = -10;
yourSlider.maximumValue = 10;
[yourSlider addTarget:self action:#selector(roundValue) forControlEvents:UIControlEventValueChanged];
- (void)roundValue{
yourSlider.value = round(yourSlider.value);
}

A flexible solution:
// define MIN_VALUE, MAX_VALUE and INTERVAL somewhere, such as 3, 18 and 3
slider.TouchUpInside += delegate {
touchUpInside();
};
/// <summary>
/// set value to one of intervals
/// </summary>
void touchUpInside(){
// get the nearest interval value
for(int i=MIN_VALUE; i<=MAX_VALUE; i=i+INVERVAL){
if(slider.Value > i && slider.Value < i + INVERVAL){
if(slider.Value - i < i + INVERVAL - slider.Value){
slider.Value = i;
}else{
slider.Value = i + INVERVAL;
}
break;
}
}
}

I know this question is old but I just want to share how I did this.
Assuming that the UISlider object has already been initialized, first, the minimum and maximum values of the UISlider object must be set:
mySlider.minimumValue = -2.0;
mySlider.maximumValue = 2.0;
Then, set the selector that will handle the changes in the slider:
[mySlider addTarget:self action:#selector(sliderDidChangeValue:) forControlEvents:UIControlEventValueChanged];
Also, set the interval (to a property). It is important that the interval is positive. (And, really, the INTERVAL MUST BE POSITIVE.)
self.interval = 0.5 //_interval is float
Declare the method(s):
- (void)sliderDidChangeValue:(id)sender
{
UISlider *slider = (UISlider *)sender;
//Round the value to the a target interval
CGFloat roundedValue = [self roundValue:slider.value];
//Snap to the final value
[slider setValue:roundedValue animated:NO];
}
- (float)roundValue:(float)value
{
//get the remainder of value/interval
//make sure that the remainder is positive by getting its absolute value
float tempValue = fabsf(fmodf(value, _interval)); //need to import <math.h>
//if the remainder is greater than or equal to the half of the interval then return the higher interval
//otherwise, return the lower interval
if(tempValue >= (_interval / 2.0)){
return value - tempValue + _interval;
}
else{
return value - tempValue;
}
}

int sliderValue = kSliderInterval * floor((slider.value / kSliderInterval) + 0.5);

UISliders do not 'increment' their value, they increase or decrease their value according to how they're touched. You can use these properties to set the slider limits:
slider.minimumValue = 0.0;
slider.maximumValue = 0.5;

i would suggest is that put the level just below the slider where you want to put value and set maximum and minimum value then the in between value can be calculated by no of point and by division and finally display in uilabel the values.
hope this will help
good luck

Related

How to move image in the background of the view? [duplicate]

This question already has answers here:
Closed 10 years ago.
I have a problem in my application i have a moving image it works fine.
But my image is also moving over a button, that i can't click when the image is before the button. How can i make sure that the image is moving on the background of my view so i can still press the button.
This is the code for the moving image
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[self navigationController] setNavigationBarHidden:YES animated:YES];
[self loadImage];
image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cow.png"]];
image.frame =self.view.bounds;
[[self view] addSubview:image];
[NSTimer scheduledTimerWithTimeInterval: 3
target: self
selector:#selector(moveImage:)
userInfo: nil repeats:YES];
}
-(void) moveImage: (NSTimer*)timer {
CGFloat x = (CGFloat) (arc4random() % (int) self.view.bounds.size.width);
CGFloat y = (CGFloat) (arc4random() % (int) self.view.bounds.size.height);
CGPoint pointOne=CGPointMake(x,y);
image.center=pointOne;
}
}
The problem lies in the fact that arc4random_uniform() calls take an upper bounds, not a 0-based count of args (as you, cleverly some would say, extrapolated). Your equation is nearly-sound, however flawed in a few places, which I've tried to correct with some documentation:
-(void)someAction:(id)sender {
NSInteger imageIndex1 = arc4random_uniform(self.images.count); //upper bounds, so no -1
NSInteger imageIndex2 = arc4random_uniform(self.images.count); //upper bounds, so no -1
NSInteger imageIndex3 = arc4random_uniform(self.images.count); //upper bounds, so no -1
_Bool b1 = true, b2 = true, b3 = true; //I can only assume you've been declaring GNU C booleans because of the lowercase false.
//be careful, in Objective-C land, BOOL is signed char.
if (imageIndex1 == imageIndex2) {
b1 = false;
imageIndex2 = arc4random_uniform(self.images.count); //upper bounds, so no -1
}
if(imageIndex1 == imageIndex3) {
b2 = false;
imageIndex1 = arc4random_uniform(self.images.count); //upper bounds, so no -1
}
if (imageIndex2 == imageIndex3) {
b3 = false;
imageIndex3 = arc4random_uniform(self.images.count); //upper bounds, so no -1
}
//You have to use ors here, otherwise your UI will never actually update, considering that in checking
//for unique factors, then reassigning to another unique factor if a check fails, one of them has got
//to be true before the UI can update, rather than all 3 at once.
//Perhaps an individual check of each boolean would be more effective.
if(b1 == true || b2 == true || b3 == true ) {
[self.picture1 setImage:self.images[imageIndex1]];
[self.picture2 setImage:self.images[imageIndex2]];
[self.picture3 setImage:self.images[imageIndex3]];
}
}
I'm guessing you're looking for a random index that isn't the current index, so that you can pick a random, different index, rather than just a random index.
- (NSUInteger)randomUnsignedLessThan:(NSInteger)max excluding:(NSUInteger)exclude {
NSInteger firstTry = -1;
while (firstTry == exclude) firstTry = arc4random() % max;
return firstTry;
}
Note that this approach will always call arc4random once, and require 1+N calls with a probability of 1/max^N, so for low ranges, and high performance requirements, you might consider a different algorithm to exclude the one index.

Changing button label not working properly with if-else method

it is probably a very simple problem but I spent already a lot of time on it and just have given up...
I have a button and a textfield for speed calculations. I want the button label change once the button is pressed (km/h >> mph >> m/s >> km/h and so on) and speed recalculated. It sometimes works fine but very often it jumps to "else" statement even if the CurrentSpeedValue is #"km/h". Could anyone help? Maybe it would be better to use switch-case method but how should it be stated?
- (IBAction)speedChange:(id)sender {
//CurrentSpeedUnit is saved to NSUserDefault in another action
if (CurrentSpeedUnit == #"km/h") {
[sender setTitle:#"mph" forState:UIControlStateNormal];
CurrentSpeedUnit = #"mph";
float speedToPrint = ([textSpeed.text floatValue]) / 1.609344;
textSpeed.text = [[NSString alloc] initWithFormat:#"%.3f", speedToPrint];
} else if (CurrentSpeedUnit == #"mph") {
[sender setTitle:#"m/s" forState:UIControlStateNormal];
CurrentSpeedUnit = #"m/s";
float speedToPrint = ([textSpeed.text floatValue]) * 1.609344 / 3.6;
textSpeed.text = [[NSString alloc] initWithFormat:#"%.3f", speedToPrint];
} else {
[sender setTitle:#"km/h" forState:UIControlStateNormal];
CurrentSpeedUnit = #"km/h";
float speedToPrint = ([textSpeed.text floatValue]) * 3.6;
textSpeed.text = [[NSString alloc] initWithFormat:#"%.3f", speedToPrint];
}
}
For string comparison you need to use
isEqualToString
For Example:
if ([CurrentSpeedUnit isEqualToString:#"km/h"])
{
// Perfrom Action
}...
You should not compare strings like that (you compare pointers but not the contents). Use isEqualToString.
i.e.
if ([CurrentSpeedUnit isEqualToString:#"km/h"]) {
...
but not your
if (CurrentSpeedUnit == #"km/h") {
It may work sometimes, but just remember to avoid comparing strings with ==

how to use the UISlider and how to set the slider on a particular values?

i am using an UIslider first time.
first i want to know how to gat value of slider positon if the range of value is 0 to 10:
second i want my slider just set at 5 different values .
like 1, 2, 3, 4, 5
slider should not set between the labeled value
first u set textfiled and add this function into code
-(IBAction)changeSlider:(id)sender
{
text_field .text= [[NSString alloc] initWithFormat:#" Value %d ", (int)slider.value];
}
I followed this tutorial for mine and it was very helpful there are variables you can set in the code such as max number and how much the slider increases each time. Link: http://www.xprogress.com/post-35-uislider-tutorial-example-how-to-use-slider-in-iphone-sdk-xcode/
In this case I set the slider in XCode to have values of: 0-3. But the slider value is float: 0.000 - 3.000.
// **** Cylinder Volume Slider ****
- (NSInteger) normalizeValueCylinderVolumeSlider:(float) value
{
NSInteger normalizedValue = 0;
if (value>1.5)
{
if (value>2.5)
normalizedValue = 3;
else
normalizedValue = 2;
}
else if (value>0.5)
normalizedValue = 1;
return normalizedValue;
}
- (IBAction)valueChangedCylinderVolumeSlider:(UISlider *)sender
{
float value = [sender value];
NSInteger normalizedValue;
// Step 1:
normalizedValue = [self normalizeValueCylinderVolumeSlider:value];
// Step 2:
if (normalizedValue>value)
{
if ((normalizedValue-value)<0.3)
sender.value = normalizedValue;
}
else if ((value-normalizedValue)<0.3)
sender.value = normalizedValue;
}
- (IBAction)touchUpInsideCylinderVolumeSlider:(UISlider *)sender
{
float normalizedValue = 0;
normalizedValue = [self normalizeValueCylinderVolumeSlider:[sender value]];
sender.value = normalizedValue;
}
- (IBAction)touchUpOutsideCylinderVolumeSlider:(UISlider *)sender
{
float normalizedValue = 0;
normalizedValue = [self normalizeValueCylinderVolumeSlider:[sender value]];
sender.value = normalizedValue;
}
On valueChanged action, (step 1) I set the value to rigid values: 0, 1, 2, 3. And (step 2) I stick the slider thumb to the rigid values if it get close by 0.3 from the rigid value.
On touchUpInside & touchUpOutside I repeat 'step 1' code from valueChanged action to fix the slider value for the case that the drag action end outside the stick range ('step 2').
The best is to put all this code in a sub-class of Slider. But this is my only first week / attempt on iOS development.

Gauge animation on iphone

I'm trying to implement a gauge animation using (+ and - buttons) on iphone, but i have no idea where to start? Any help is really welcome. See the image below (this is what I'm trying to do). Thanks for your help.
Here is some open source code (with an example) that implements the gauge view. You of course would still need to do the buttons yourself, and possible add a different visual style.
http://www.cocoacontrols.com/platforms/ios/controls/meterview
You need to rotate the needle based on the angle... Here is the logic
You can refer my answer here... Rotating a UIImageView around a point over 10 seconds?
fireInterval = 10;
//Adjust starting and ending angle
mStartingAngle = 45;
mEndingAngle = 180;
//Implementation
-(void) startTimer
{
mPreviousTime = [NSDate timeIntervalSinceReferenceDate];
}
In the loop
-(void) updateFunction
{
NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate];
//NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
//Mapping values between mStartAngle and mEndAngle
mCurrentAngle = (((timeNow - mPreviousTime) * (mEndingAngle - mStartingAngle)) / (previousTime+fireInterval - mPreviousTime)) + mStartingAngle;
if( mPreviousTime + fireInterval <= timeNow )
{
NSLog(#"10 seconds completed");
mPreviousTime = timeNow;
}
}
And rotate the needle based on mCurrentAngle....

Can we change dynamically the interval of "schedule"?

I'm making a game on iPhone using cocos2d, and I have a question.
In my init method I'm doing this :
[self schedule:#selector(newMonster:) interval:1];
It create a new monster every second.
But I'd like that the interval change over time. For example :
The 10 first seconds of the game: a new monster appears every 1 second.
Then for 10 seconds: a new monster appears every 0.8 second.
And after every 0.5 second...
How can I do that?
Thanks !
You may try this- (I have copied some code from #bddckr)
Initial time:
self.monsterSpawnStartDate = [NSDate date];
self.lastTimeScheduledBefore = 0;//new var
Scheduled Method to create monster
- (void)scheduledMethod {
NSTimeInterval seconds = [[NSDate date] timeIntervalSinceDate:monsterSpawnStartDate];
[self newMonster]; // Let a new monster spawn
if (seconds >= 20.0 && lastTimeScheduledBefore == 10){
[self unschedule:#(scheduledMethod)];
[self unschedule:#(scheduledMethod) interval:0.5];
lastTimeScheduledBefore = 20;
}
else if (seconds >= 10.0 && lastTimeScheduledBefore == 0){
[self unschedule:#(scheduledMethod)];
[self unschedule:#(scheduledMethod) interval:0.8]
lastTimeScheduledBefore = 10;
}
}
You can modify it as your need. You can use mod if it goes through a cycle.
Make an instance variable and property of NSDate called monsterSpawnStartDate, make it an retaining property and synthesize it.
As soon as your first monster should be created, set it:
self.monsterSpawnStartDate = [NSDate date]; // Current date and time
And replace your code by this:
[self schedule:#selector(adjustMonsterSpawnRate) interval:0.1]; // Seems like you want it to fire every 0.1 seconds
Implement adjustMonsterSpawnRate like this:
- (void)adjustMonsterSpawnRate {
NSTimeInterval seconds = [[NSDate date] timeIntervalSinceDate:monsterSpawnStartDate];
if (((seconds <= 10.0) && (seconds % 1.0)) || ((seconds <= 20.0) && (seconds % 0.8)) ((seconds > 20.0) && (seconds % 0.5)))
[self newMonster]; // Let a new monster spawn
}
I think a better option would be to use a scheduled function for timing and use accumulated time to trigger the enemy creation as follows
self.time_since_last_monster = 0
[self schedule:#selector(new_monster:) interval:0.3];
-(void) new_monster:(ccTime)dt{
self.time_since_last_monster += dt;
if(self.time_since_last_monster > monster_interval){
self.time_since_last_monster -= monster_interval;
[self create_new_monster];
// at this point based on some condition, you can now change monster_interval
}
}
This would give more flexibility.
I'm pretty dumb, so here's what I'd do:
in the .h set a float
float nextMonsterIn;
then in the body
nextMonsterIn = 1.0;
[self scheduleOnce:#selector(newMonster:) interval:nextMonsterIn];
[self schedule:#selector(kickUpDifficulty:) interval:10];
- (void) newMonster : (ccTime) dt
{
[self scheduleOnce:#selector(newMonster:) interval:nextMonsterIn];
//-----make a monster-----
}
- (void) kickUpDifficulty : (ccTime) dt
{
if(nextMonsterIn == 1.0)
nextMonsterIn = 0.8;
else if(nextMonsterIn == 0.8)
{
nextMonsterIn = 0.5;
[self unschedule:#selector(kickUpDifficulty:)];
}
}
Basically every time I call newMonster i'd recursively re-schedule the newMonster based on my current delay, then I can adjust the delay in a timer or every time a monster is killed or wherever.