I have a UISlider that has two text boxes attached to it. Think of it like a tip calculator. Think about a receipt: it has a spot for you to put the tip, and then the final value. Let's add a slider into the mix.
So now we have two text fields (tip percentage and tip amount) and the slider. When the slider moves it calls a method that updates the two text boxes according to the value that the person has selected with the slider.
[self.slider addTarget:self
action:#selector(sliderValueChanged:)
forControlEvents:UIControlEventValueChanged];
-(void)sliderValueChanged:(id)sender
{
tipPercent.text = [NSString stringWithFormat:#"%d", (int)slider.value];
tipPercentDbl = (int)slider.value;//tipPercent as Dbl
tipDbl = (totalDbl * (tipPercentDbl/100));//tip as Dbl
tip.text = [NSString stringWithFormat:#"%.2f", tipDbl];
tipPercent.text = [NSString stringWithFormat:#"%.0f", tipPercentDbl];
totalWithTipDbl = (totalDbl+tipDbl);
totalWithTip.text = [NSString stringWithFormat:#"%.2f", totalWithTipDbl];
}
This works perfectly. What I want to do now (and am having trouble figuring it out) is how to change the value when the text fields are changed. i.e. someone manually enters in their own tip, how to update the slider and the tip percentage; or if someone manually enters in a tip percentage, how to update the slider and the tip value.
What would be the best way to do this?
This is fairly easy. I don't know all the variables you used, so substitute your own when you try the code. When the keyboard resigns, call the method:
- (void)updateTheSliderAndTipPercentage; {
float percentage = tipTheyEntered / totalCost;
[slider setValue:percentage animated:YES];
percentage *= 100; // This is if you want the percentage in [0,100].
tipPercent.text = [NSString stringWithFormat:#"%f", percentage];
}
EDIT: In order to know when you call this method, simple check:
- (BOOL)textFieldShouldReturn:(UITextField *)textField; {
if(textField == tipTheyEnteredTextField){
[self updateTheSliderAndTipPercentage];
}
}
Hope that helps!
Related
I have a UILabel in my class and I would like the view to display the number but to count up to the number. For example, If the number was 368, it would climb quickly to the 250-300's then start to slow down as it gets to the number. Now this number will not always be 368, the number varies. It could be 6 or 129 or 1023 so it can't be a set-in-stone number. I obviously know how to create the UILabel as I already have it being used in my app, I just need help with counting upwards to it.
I have a "Player view", blah blah blah they get a score and it is passed to another view "Gameover view" and the score is display in a the UILabel.
Here is the code for the "Player view" to pass the data:
//finalScore is a int and so is currentScore
second.finalScore = self.currentScore;
Here is the code for the "Gameover view" to pass the data:
- (void)viewWillAppear:(BOOL)animated {
// scoreLabel is the IBOutlet to the UILabel in IB for displaying the score.
self.currentIndex++;
if(self.currentIndex == [self.numbersArray count]) self.currentIndex = 0;
self->scoreLabel.text = [NSString stringWithFormat:#"%d",self->finalScore];
}
Thanks in advance!
I figured it out myself. I found this control and it works just as I need it to! Click Here
You can update the UILabel object in a loop, using the Timer. As time progresses at a certain interval, "slow it down" by adding on the difference in time. Sample code for updating a UI object via Timer is a common bit of code on the Internet, as it's the way you code progress bars.
how to use the progress bar in the iphone app
Just call this method every certain interval (ex every 0.1 seconds), using a NSTimer
It will increment the value up to the target number.
-(void)countUp:(id)sender {
int targetNumber = yourNumber;
int currentNumber = [[myLabel text] intValue];
// Calculate the increment for this time. Mess with this for different speeds.
// Just multiply some of the numbers by some constants (ex. 2) until you
// achieve the desired effect.
double increment = (targetNumber - currentNumber) / targetNumber;
NSString *newValue = [NSString stringWithFormat:#"%f",currentNumber + increment];
[myLabel setText:newValue];
if ([newValue doubleValue] >= targetValue) {
[(NSTimer *)sender invalidate];
}
}
For the timer:
[NSTimer scheduledTimerWithInterval:0.1
target:self
selector:#selector(countUp:)
userInfo:nil
repeats:YES];
using literals it become quite easy to play
UILabel * label;
label.text = #(label.text.integerValue+1).stringValue;
How would you go about mimicing the iPhones keypad input. So that when you click one 1 is displayed then 2 then it is 12... so on and so forth along with the ( ) -. I don't want to use the actual phone app because I'm creating a false dialer, but I want it to look and function kind of like the actual thing.
Any ideas would be greatly appreciated thanks.
EDIT:
Ok so I put in all the buttons needed but I ended up making them all individual buttons. THey are all linked including the label and this is what one button and the updater looks like.
-(IBAction)zeroButton:(id)sender{
self.enteredPhoneNumberString = [self.enteredPhoneNumberString stringByAppendingString:[NSString stringWithFormat:#"%d", "0"]];
[self updateFormattedPhoneNumberLabel];
}
-(void)updateFormattedPhoneNumberLabel {
if ([self.self.enteredPhoneNumberString length] > 3) {
NSString *firstThree = [self.enteredPhoneNumberString substringToIndex:2];
NSString *lastSet = [self.enteredPhoneNumberString substringFromIndex:2];
self.label.text = [NSString stringWithFormat:#"%#-%#", firstThree, lastSet];
}
else if ([self.self.enteredPhoneNumberString length] > 7) {
NSString *firstThree = [self.enteredPhoneNumberString substringToIndex:2];
NSString *secondThree = [self.enteredPhoneNumberString substringToIndex:2];
NSString *lastSet = [self.enteredPhoneNumberString substringFromIndex:2];
self.label.text = [NSString stringWithFormat:#"(%#) %#-%#", firstThree, secondThree, lastSet];
}
}
I had also tried it with the "" not being around the numbers being appended. Any idea why nothing is being displayed?
NEW EDIT:
I added enteredPhoneNumberString = #""; and with the numbers formatted the way you original had it displays the numbers. The main issue I'm having now is getting it so that the () and - pop up in the right spots.
I would suggest creating a grid of UIButtons that mimics the numpad, these buttons all call a method such as keyPadButtonTouchedUpInside:(id)sender and have a tag that corresponds to the number it represents.
Implementation of keyPadButtonTouchedUpInside:(id)sender may look like...
- (void)keyPadButtonTouchedUpInside:(id)sender {
UIButton *touchedButton = (UIButton *)sender;
if (touchedButton.tag <= 9) {
self.enteredPhoneNumberString = [self.enteredPhoneNumberString stringByAppendingString:[NSString stringWithFormat:#"%d", touchedButton.tag]];
[self updateFormattedPhoneNumberLabel];
} else {
// maybe some other code for pounds/stars entered on the keypad if you have these
// you will also be checking if the user hit the backspace key and trim your
// phone number string by 1
}
}
Now you need to implement updateFormattedPhoneNumberLabel
This will look at the instance NSString variable self.enteredPhoneNumberString and update a UILabel that you have in place to display the number.
updateFormattedPhoneNumberLabel might look like...
- (void)updateFormattedPhoneNumberLabel {
if ([self.self.enteredPhoneNumberString length] > 3) {
NSString *firstThree = [self.enteredPhoneNumberString subStringToIndex:2];
NSString *lastSet = [self.enteredPhoneNumberString subStringFromIndex:2];
self.formattedPhoneNumberLabel.text = [NSString stringWithFormat:#"%#-%#", firstThree, lastSet];
} else if ....
// more conditions to check for other lengths of the
// entered number and continue with the proposed formatting methods.
Hopefully that gets you down the path, there may be more efficient methods for doing this but in reality its not an intensive operation so I wouldn't worry to much about optimization unless you see some kind of entry lag which I wouldn't expect.
EDIT
I would probably update the formatting conditions so that the formatting happens in the following behavior.
1-3 numbers entered shows as "1", "12", or "123"
4-7 numbers entered shows as "123-4", "123-45", "123-456", or "123-4567"
8-10 numbers entered show as "(123) 456-78", "(123) 456-789", or "(123) 456-7890"
11 numbers entered show as "1+(234)-567-8901"
Anything more than 11 I would just show a string of numbers, unless you want to get into formatting non-us numbers. You should also play around with entering numbers in the Phone App to see how it responds if you want to mimic it completely.
So basically in this code I placed below there is a couple things I would like to accomplish. 1) In that first one I would like the Text Field to close after done is pressed, but it is not doing so. (Found that code on other forums). 2)On that first button when it is pressed down I would like it to send a time to be saved for when the button is released. 3) On release of that button I would like it to calculate the time between the two times along with some other calculations later.
Problem that I am mainly getting here is the error from the NSTimeInterval. It keeps telling me that NSTimeInterval is incompatiable with type NSTimeInterval. So a double is incompatible with a double??? (I have also tried it with NSTimeInterval *timePassed in the .h and just trying to set timePassed = to it and it doesn't work either. Similar error happens.
#import "MphViewController.h"
#implementation MphViewController
#synthesize speed, distance;
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(IBAction)triggerDown:(id)sender{
timeStart = [NSDate date];
}
-(IBAction)triggerUp:(id)sender{
NSInteger *dist;
NSString *display;
NSTimeInterval *timePassed = [timeStart timeIntervalSinceNow];
if ([distance.text length]== 0) {
display = #"Please enter a distance";
}
else{
dist = atoi(distance.text);
display = [[NSString alloc] initWithFormat:#"%d MPH",dist];
}
speed.text = display;
[display release];
}
Also if you have a chance to glance at the else statement. I'm not sure if that will work (seeing is after I enter a distance I still cant get rid of the numberpad). Id like to pass mph once it is calculated into that to be displayed on the screen. Very confused with how parsing is done on obj c. Anyways thanks for any and all help.
As for the textField part. My textField that it is assigned to is distance. Should that Bool be written differently to have distance in it or is that just the way it is supposed to be written?
You are denoting primitive types as pointers where they do not need to be. Remove the star (*) from the NSInteger and NSTimerIntervaldeclaration. The if check looks fine but instead of atoi just use:
dist = [distance.text integerValue];
Edit:
Notice a couple of memory management issues.
1 . Make sure you properly retain/release the date then later release it in dealloc.
-(IBAction)triggerDown:(id)sender{
[timeStart release];
timeStart = [[NSDate alloc] init];
}
2 . Your if statement will result in trying to release an NSString literal which likely will not crash but is incorrect memory management. Just use an autoreleased string and remove the [display release];
...
else{
dist = [distance.text integerValue];
display = [NSString stringWithFormat:#"%d MPH",dist];
}
speed.text = display;
}
I'm new to iPhone development, so my apologies if this is a ridiculous question.
I'm following a sample from a book where it creates a exchange rate UIPicker and when you select one of the entries, it displays the conversion of US dollars into whatever currency is picked.
I want the value to be updated in my label before I start changing the value from the picker.
The very first time i enter my US dollar value in the textbox and I click on the "Return" button, i want the label to update and displays its equivalent value in whatever currency is currently selected in the picker.
I have the correct code in the didSelectRow event, and that part works as long as i start spinning the picker's component wheels, so I thought I'd take that code and put it in a function which would have one parameter i.e. row and this function would then be called from didSelectRow where the row parameter would be passed and then I would:
This is the code from the didSelectRow:
float rate = [[exchangeRates objectAtIndex:row] floatValue];
float dollars = [dollarText.text floatValue];
float result = dollars * rate;
NSString *resultString = [[NSString alloc] initWithFormat:#"%.2f USD = %.2f %#", dollars, result, [countryNames objectAtIndex:row]];
resultLabel.text = resultString;
[resultString release];
Call this function when the "Did End on Exit" event for the textbox but my I'm having two problems:
What is the correct way to write the function. Whatever way I write the function, I get various errors/warnings
How do i get the currently select row of the picker, so that I can pass it to this function when the "Did End on Exit" event occurs when i click on the "Return" button.
Thanks
T.
I am not sure, I completely understood you what exactly you are trying to do here. but still I am going ahead what you can do here is:
first of all declare an class variable of type int which will store the row index whenever didSelectRow delegate method will be called, mean time create a method like:
-(void)updateLabel:(int) rowIndex
{
float rate = [[exchangeRates objectAtIndex:row] floatValue];
float dollars = [dollarText.text floatValue];
float result = dollars * rate;
NSString *resultString = [[NSString alloc] initWithFormat:#"%.2f USD = %.2f %#", dollars, result, [countryNames objectAtIndex:rowIndex]]; // here it will go rowIndex which is the row value you stored in your variable
resultLabel.text = resultString;
[resultString release];
}
and call this method when you hit return.
I hope this helps you.
~Manoj
I'm putting up a CalculatorApp for the iPhone and there is just one thing that i need to end, the floating-point!
As in normal calculators, i need to do something so that will only permit one "." .
Can you dudes help me?
you have a few ways to go, such as, NSString's rangeOfString method, e.g.
#define FLOATING_POINT_STRING #"."; // set this to #"." or #"," according to the floating point type you want to use
float calculatorText = 45.194; // set this to whatever the label says, or you can skip the float => string conversion as shown below
NSString *text = [NSString stringWithFormat:#"%f", calculatorText];
if ([text rangeOfString:FLOATING_POINT_STRING].location != NSNotFound)
{
// do nothing, there is a floating point
}
else
{
// append FLOATING_POINT_STRING to the label
}
Good luck ;)
Are you using a UIButton for the decimal point button? If so, you could simply disable it as soon as it is pressed. And then of course, re-enable it when "clear" or "equals" or whatever is pressed:
[buttonDecimalPoint setEnabled: NO];