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

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.

Related

Sprite Kit Calling a random method

I am currently making a game in sprite kit and i have 8 methods, I have written all the timing code E.T.C so it calls a method every 1 second, but i want it to call a random one of the eight methods, I have been trying to get this working for weeks, any help would be muchly appreciated, Here is my timing code -
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 5) {
self.lastSpawnTimeInterval = 0;
[self shoot1];
}
}
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
As you can see instead of [self shoot1]i want it to randomly call one of the eight methods, Also all the methods are named Shoot1, Shoot2, all the way to Shoot8. Thankyou
I can think of two options...
Option 1
Just pick a random number between 1 and 8, and use a switch statement:
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 5) {
self.lastSpawnTimeInterval = 0;
int randomNumber = arc4random_uniform(8);
switch(randomNumber) {
case 0:
[self shoot1];
break;
case 1:
[self shoot2];
break;
// ... cases 2-6
case 7:
[self shoot8];
break;
}
}
}
Option 2
Rewrite your shootN methods so that you only have one method that takes an integer as a parameter:
- (void)shoot:(int)index;
Then, you can just do the following:
[self shoot:arc4random_uniform(8)];
You could also live dangerously...
int random = arc4random() % 8;
NSString *selectorName = [NSString stringWithFormat:#"shoot%i", random];
SEL selector = NSSelectorFromString(selectorName);
if ([self respondsToSelector:selector]) {
[self performSelector:selector];
}
This will, by the way, generate a warning when using ARC.

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.

Reduce number in text box by one for each button tap

I'm relatively new to Objective-C so this might be really simple to do: I have a text box in my application that displays an ammo count, so each time the user taps a fire button the number in the text box will go down by one (12 > 11 > 10, etc) to 0. I have tried using for and if statements, but they are not working (I may have used incorrect syntax). This is what I'm using right now, but obviously I need the
- (IBAction)fire {
[ammoField setText:#"11"];
}
- (IBAction)reload {
[ammoField setText: #"12"];
}
The simplest way would be to convert the text to a number, decrement that and the reset the text, i.e. replace the code in the fire method with:
NSInteger ammoCount = [ammoField.text integerValue];
ammoCount--;
ammoField.text = [NSString stringWithFormat:#"%d", ammoCount];
But don't do this, it will make baby Steve Jobs cry.
A better way would be to add a new variable to the class of type UIInteger that tracks the the number of bullets, i.e.:
// in interface
NSInteger _ammoCount;
...
// in implementation
- (IBAction)fire {
_ammoCount--;
if (_ammoCount <= 0) {
_ammoCount = 0;
fireButton.enabled = NO;
}
[ammoField setText: [NSString stringWithFormat:#"%d", _ammoCount]];
}
- (IBAction)reload {
_ammoCount = 12;
[ammoField setText: [NSString stringWithFormat:#"%d", _ammoCount]];
fireButton.enabled = YES;
}
Oh, and don't forget to call reload at some point early on to ensure _ammoCount and ammoField get initialised.
Set Instance Integer
int x;
set value of it
x = 12;
do change in method
- (IBAction)fire {
[ammoField setText:[NSString stringWithFormat:#"%i",x]];
x--;
}
set the value of count in viewdidload with an int variable
fire method decrease the count by 1
and reload method to return value to 12
log or use values accordingly
Try this:-
int i;
-(void)ViewDidLoad
{
i=12;
}
- (IBAction)fire
{
[ammoField setText:[NSString stringWithFormat:#"%d",i]];
i--;
}
- (IBAction)reload {
i = 12;
[ammoField setText: [NSString stringWithFormat:#"%d", i]];
}
Hope it will work for you. Thanks :)

Problem with the counter of collisions

Here is my code :
-(void)detectCollision{
imageView.center = CGPointMake(imageView.center.x + X, imageView.center.y + Y);
if(CGRectIntersectsRect(imageView.frame,centre.frame)){
label.text= [NSString stringWithFormat:#"%d", count];
++count;
}
I have a CADisplayLink(60fps) on detectCollision.
I want to increment "count" of one every time "imageView" collide with "centre", but my problem is that count increment too fast, every time there is a collision it increment of near 100 or 200, I don't know why. How can I solve this ?
Its because everytime the frames start intersecting in,
if(CGRectIntersectsRect(imageView.frame,centre.frame))
your condition will be true until the frames separate and the count increases over 100 in the CADisplayLink
so you can use a BOOL and set it to true when the frames first intersects. then check whether they are separate and make the BOOL back to false.
initialize BOOL intersectFlag to false in init. I assume that the frames wont intersect initially.
-(void)detectCollision
{
imageView.center = CGPointMake(imageView.center.x + X, imageView.center.y + Y);
if(!intersectFlag)
{
if(CGRectIntersectsRect(imageView.frame,centre.frame))
{
intersectFlag = YES;
label.text= [NSString stringWithFormat:#"%d", count];
++count;
}
}
else
{
if(!CGRectIntersectsRect(imageView.frame,centre.frame))
{
intersectFlag = NO;
}
}
}
to find out collision u should use with bounds not frame
bounds - size inside of object
frame - offset from superview x,y + size(bounds)
here i assume u are in portrait mode
-(void)detectCollision{
if(CGRectContainsPoint( imageView.bounds, CGPointMake(160, 240)) ){
label.text= [NSString stringWithFormat:#"%d", count];
++count;
}
}

Setting interval value for UISlider

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