IF statement in Objective-C in Xcode - iphone

In Xcode, I'm trying to make a button that changes it's text, relative to what the text currently is. For example: If the button says "1" and it is pressed, I want the text to change to "2" and "2" to "3" and so forth, here's the snippet of code that's giving me trouble:
if (magicButton.titleLabel = #"1") {
[magicButton setTitle:#"2" forState:UIControlStateNormal];
}
Xcode gives me this error "Assignment to readonly property" on line one of the snippet. I'm pretty new to Objective-C and iPhone App development, so maybe it's something crazily obvious and simple. Please don't mind if that's the case.
Here's a paste of my implementation file if it would help at all.
Thanks in advance.

'=' is for assignment while '==' is for comparison. But in the case of string comparison you should use isEqualToString method. Something like this:
if ([magicButton.titleLabel.text isEqualToString: #"1"]) {
[magicButton setTitle:#"2" forState:UIControlStateNormal];
}
PS. Also note that you should get the UILabel's text property

If you want to be changing the button text relative to what it is with no restrictions, you can't make a million if statements. You should get the value of the button title (if it even has a title) and just add 1 to it, like so:
NSString *string = randomButton.titleLabel.text;
if ([randomButton.titleLabel.text length] == 0) { //Check if there is not a title on the button
[randomButton setTitle:#"1" forState:UIControlStateNormal]; //And if there isn't, set it to "1"
}
else {
int yourInt = [string intValue]; //Convert to int
int nextInt = yourInt + 1; //Add one to value
NSString *finalString = [NSString stringWithFormat:#"%d",nextInt]; //Convert back to string
[randomButton setTitle:finalString forState:UIControlStateNormal]; //Finally set it as the title
}

Related

How to get instance variable name?

I created a simple iPhone screen with two UIButtons programmatically like below.
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *buttonOne = [UIButton buttonWithType:UIButtonTypeRoundedRect];
buttonOne.frame = CGRectMake(60, 70, 200, 40);
[buttonOne setTitle:#"One" forState:UIControlStateNormal];
[self.view addSubview:buttonOne];
UIButton *buttonTwo = [UIButton buttonWithType:UIButtonTypeRoundedRect];
buttonTwo.frame = CGRectMake(60, 250, 200, 40);
[buttonTwo setTitle:#"Two" forState:UIControlStateNormal];
[self.view addSubview:buttonTwo];
}
Now on press of button with title as "One", I want to get the variable name as "buttonOne", similarly on press of button with title as "Two" I want to get the variable name as "buttonTwo".
I am not finding a way to get the variable name. Any help? Thanks in advance
First off I'd like to disclaim that this is not good coding style. I assume you're doing this because of some special/unique case, or as a proof of concept. In a production app, this is NOT the way to go. You should set your buttons as properties/ivars and you can compare them when they're pressed, or you can assign tags, or separate targets/selectors for each button. Anything you can do to avoid this approach is good because to be honest this approach is kind of terrible (see note at the end of next paragraph about nil/0 values).
You can check out this code below from a previous SO answer - it will return the name of the ivar given the pointer. However, you have to declare your buttons as ivars and not local variables. Also, if two ivars are nil, it will report the same. So this will only work if all your object ivars are not nil, and your primitive type ivars are not 0.
#import <objc/objc.h>
- (NSString *)nameOfIvar:(id)ivarPtr
{
NSString *name = nil;
uint32_t ivarCount;
Ivar *ivars = class_copyIvarList([self class], &ivarCount);
if(ivars)
{
for(uint32_t i=0; i<ivarCount; i++)
{
Ivar ivar = ivars[i];
id pointer = object_getIvar(self, ivar);
if(pointer == ivarPtr)
{
name = [NSString stringWithUTF8String:ivar_getName(ivar)];
break;
}
}
free(ivars);
}
return name;
}
So add a method buttonPressed: as follows:
- (void)buttonPressed:(id)sender {
if ([sender isKindOfClass:[UIButton class]]) {
NSString *buttonName = [self nameOfIvar:sender];
//Now you can do something with your button name
}
}
Source of first block of code: Get property name as a string
we can get only button title name by this way buttonOne.titleLabel.text.
we can't get variable name

Delete Key in UILabel is not working when code is correct

I am creating a calculator app and the calculator screen is a UILabel. I am having trouble with a delete key. Here is my Code:
.h
IBOutlet UILabel *display;
.m
- (IBAction)Del
{
[display.text substringToIndex:display.text.length -1];
}
it has no errors and runs in the simulator perfectly but does not actually work. Can anyone help.
-substringToIndex: creates a copy of a part of the string to which it is sent.
What you have here creates such a string, and does nothing with it.
I suspect you want to assign that string to something, say, the display.text property:
- (IBAction)Del {
display.text = [display.text substringToIndex:display.text.length -1];
}
You are ignoring the return value of the substringToIndex: method and you do not update the label's text.
You want something like this:
- (IBAction)Del {
NSString *oldText = display.text;
if (oldText.length > 0) {
NSString *newText = [oldText substringToIndex:oldText - 1];
display.text = newText;
}
}
This also guards against trying to delete from an empty label.

Mimic the iPhones phone keypad input

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.

Slider / Text Box Exchange Data

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!

Only one comma/point in the calculator! Objective-C for iPhone

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];