I'm developing a calculator app and would like to add 10 storage registers that the User can store numbers to. The calculator's storyboard has a "STO" button that is pressed when the User wants to store an entry. The next numeric button pressed (button 0, button 1 ... button 9) would signify the register to store the entry in.
The app currently contains the method "STOButtonPressed":
- (IBAction)STOButtonPressed:(UIButton *)sender{
STOButtonPressed = YES;
}
I have a method for entering numbers into the calculator, called digitPressed:
- (IBAction)digitPressed:(UIButton *)sender{
NSString* digit = sender.currentTitle;
[_audioPlayer play];
if(!(self.dotNotation && [digit isEqualToString:#"."])){
if([digit isEqualToString:#"."])
self.dotNotation=YES;
if(self.userIsInTheMiddleOfTyping){
self.displayLabel.text = [self.displayLabel.text stringByAppendingString:digit];
}
else
{
self.displayLabel.text = digit;
self.userIsInTheMiddleOfTyping = YES;
}
}
}
Each number button on the calculator in the storyboard is tagged (button "0" is tag "0", button "1" is tag "1", etc....).
After pressing the "STO" button, I'd like the next button (0 thru 9) entry to be the storage register number. And I'd like to set the storage register number within the STOButtonPressed method. Not sure if that's possible, or how to do it if it is. I currently have several "IF statements" in the digitPressed method for determining the storage register number (not shown here). But that seems very cumbersome and the method has gotten very messy. I'd like to keep all code for the storage feature within the STOButtonPressed method. I've been working this unsuccessfully for many days, and feel I'm missing something. Can someone tell me how to make set the storage register number within the STOButtonPressed method, if that's even possible?
I'm using Xcode 5.
If you have set your button's tags properly, it should be pretty straightforward:
in your properties, add:
#property (nonatomic, assign) BOOL hasPressedSTOButton;
and change this because you don't want confusion between your var and your method name:
- (IBAction)STOButtonPressed:(UIButton *)sender{
self.hasPressedSTOButton = YES;
}
And change your tags to 1-10 instead of 0-9 because you want to make sure you are checking a button with a non-zero tag, and not some other button.
then change your digitPressed like this
- (IBAction)digitPressed:(UIButton *)sender{
NSString* digit = sender.currentTitle;
[_audioPlayer play];
if(!(self.dotNotation && [digit isEqualToString:#"."])){
if([digit isEqualToString:#"."])
self.dotNotation=YES;
if(self.userIsInTheMiddleOfTyping){
self.displayLabel.text = [self.displayLabel.text stringByAppendingString:digit];
}
else
{
self.displayLabel.text = digit;
self.userIsInTheMiddleOfTyping = YES;
}
} else if (sender.tag != 0) {
//store your stuff here. Tags range from 1 to 10. Use sender.tag - 1 if you want the values to range from 0 to 9.
}
}
Related
I'm expecting to get a little help with a UIButtons staying .hidden. I'm new to this site so please give me a min to best describe this problem I face.
Below is a picture of 2 UIButtons, in the middle of these UIButtons there is another one called OnRoute. Once the Acknowledged button is pressed it is hidden to which sends a status and reveals the OnRoute UIButton. Now the Acknowledged button is hidden you will only see on screen under the Runsheet button the OnRoute button to which you also press that sends a status and then hides it self.
Once these buttons are pressed you are sent to a UITableView and at this point all is well, but when you go back to the menu screen the buttons are reappear as if the buttons have not been pressed. And you can repeat over and over sending status.
The idea of this is to send a job status once the buttons are pressed which in turn shows on software on a server. Once these have been sent and the UIButtons hide for that job number, I would like to keep them hides until job has gone from hand set.
This is complex problem but if anyone has any ideas of this, I would really be thankful.
//This is in ViewDidLoad
self.onroute.hidden = YES;
NSNumber *num = [NSNumber numberWithInt:10.00];
self.acknow.hidden = YES;
if((self.consignment.cur_status_no < num) || [self.consignment.newjob isEqual:#(YES)]){
self.acknow.hidden = NO;
//This is in IBAction
- (IBAction)acknowledgebtn:(id)sender {
if (self.onroute.hidden == YES){
self.acknow.hidden = NO;
self.onroute.hidden = NO;
self.acknow.hidden = YES;
//and this is for the other IBAction
if (self.acknow.hidden == YES){
self.onroute.hidden = YES;
As I'm new to the site it will not let me post picture of UIButton sorry for this.
My suggestion would be to use some booleans instead of relying on the buttons hidden property. Then save the booleans when transferring to a new view. Then when you return to the main menu check the booleans and see what should be hidden and what should not be.
Also when I name variables I like to pretend that someone else will be looking at my code. So instead of just onroute as the button name, I would make it onrouteBut. This makes it a lot easier when I go back through my code as well so I know exactly what each variable is just by looking at the name.
As for the code I don't know how you are presenting views, so I can't really give a full answer. But I think this will help.
in your .h
#property (nonatomic) BOOL onrouteBool;
#property (nonatomic) BOOL acknowBool;
//whatever other bools you need instead of using button.hidden == YES/NO
in your .m
#synthesize onrouteBool, acknowBool;
-(void)viewDidLoad {
onrouteBut.hidden = YES;
onrouteBool = YES;
NSNumber *num = [NSNumber numberWithInt:10.00];
acknowBut.hidden = YES;
acknowBool = YES;
if((self.consignment.cur_status_no < num) || [self.consignment.newjob isEqual:#(YES)]) {
acknowBut.hidden = NO;
acknowBool = NO;
}
}
-(IBAction)acknowledgeBtn:(id)sender {
if (onrouteBool == YES) {
acknowBut.hidden = NO;
onrouteBut.hidden = NO;
acknowBool = NO;
onrouteBool = NO;
//this part doesn't make sense you set the button to visible and then hidden right after
acknowBut.hidden = YES;
acknowBool = YES;
}
}
-(IBAction)onrouteBtn:(id)sender {
if (acknowBool == YES) {
onrouteBut.hidden = YES;
onrouteBool = YES;
}
}
So now before you transition to your next view call this method to save the bools
-(void)saveTheBools {
//save the bools however you want before you transition the view
//one way is nsuserdefaults
[[NSUserDefaults standardUserDefaults]setBool:onrouteBool forKey:#"onrouteBool"];
[[NSUserDefaults standardUserDefaults]setBool:acknowBool forKey:#"acknowBool"];
[[NSUserDefaults standardUserDefaults]synchronize];
//how you save them
}
then when you transition back to the main menu check the bools to see if the buttons should be hidden
-(void)checkTheBools {
onrouteBool = [[NSUserDefaults standardUserDefaults] boolForKey:#"onrouteBool"];
acknowBool = [[NSUserDefaults standardUserDefaults] boolForKey:#"acknowBool"];
if (onrouteBool == YES) {
onrouteBut.hidden = YES;
}
else {
onrouteBut.hidden = NO;
}
if (acknowBool == YES) {
acknowBut.hidden = YES;
}
else {
acknowBut.hidden = NO;
}
//whatever else you need to hidden or make visible
}
This is all just to give you some ideas of what to do. Use what you need to make it work. This is how I would do it, I don't know if this is best way to do it but it's a starting point. I can't really give a specific answer without seeing all of your code, since I don't know how you're transitioning views, what you are initializing, retaining, etc.
Hope this helps you out, if not my bad. Just keep working at it and you'll find something that works for you eventually.
edit:
As for the status problem you are having I can't really help because I don't have the code to look at. I think it probably has to do with saving your variables so you can access them across classes. So like I showed you how to save the booleans and use them you probably will have to do something similar to check if the status has sent or not.
I suggested using nsuserdefaults because that is the easiest thing to do, however it is not the best to rely on that for saving all of your variables. You can also look into singletons, core data, or anything that will allow you to save the variables that you need across classes. You just have to find the way that works best for what you are trying to do.
The only way you are going to learn is to struggle at times, do some research, and try different things until you find a solution. Also take advantage of the resources apple provides you with as a developer. I think you will be able to figure this one out. Good luck
Just wanted to update anyone having this problem, I managed to fix this using doubleValue.
onroute.hidden = YES;
onrouteBool = YES;
NSNumber *num1 = [NSNumber numberWithDouble:10.00];
if(([self.consignment.cur_status_no doubleValue] < [num1 doubleValue] ) ) {
if([self.consignment.newjob isEqual:#(NO)]) {
onroute.hidden = NO;
onrouteBool = NO;
}
}
acknow.hidden = YES;
acknowBool = YES;
if([self.consignment.newjob isEqual:#(YES)]) {
acknow.hidden = NO;
acknowBool = NO;
}
Thanks again for all your help.
I have designed a signup form in ios with four UITextFields and a UIButton. I have set the buttons' enabled property to NO by default. Now I want to enable the button only when all the four textfields are filled. Can you please help me out with this as I a new to ios, and stuck with this issue.
A better way would be to use the didChange method like the UITextViewDelegate method, but as we know the UITextFieldDelegate does not have a didChange method. You can manually add behaviour. You can use the shouldChangeCharactersInRange: method, but personally I would advise not to override methods unless you absolutely have to.
You can add behaviour using:
[myTextField1 addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];//And so on for all your text fields
And in the target method:
- (void)textFieldDidChange:(UITextField*)textField{
if (myTextField1.text.length > 0 && myTextField2.text.length > 0 && myTextField3.text.length > 0 && myTextField4.text.length > 0){
myButton.enabled = YES;
} else {
myButton.enabled = NO;
}
}
EDIT:
Further, if you want to make sure they are enabled only if the user has entered valid text, and not empty spaces, you may use the following to get the trimmed text, check if this trimmed text has length > 0:
NSUInteger textLength = [myString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
in your .h file
#interface YourViewController : UIViewController <UITextFieldDelegate>
in your .m file
Write this in viewDidLoad
self.btnSignUp.enable=NO; //button is disable by default
self.textField1.delegate=self; // set delegate of text field
self.textField2.delegate=self;
self.textField3.delegate=self;
self.textField4.delegate=self;
Write this text field's delegate method
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if ([textField1.text length]>0 && [textField2.text length]>0 && [textField3.text length]>0 && [textField4.text length]>0) // check if all the textfields are filled
{
self.btnSignUp.enabled:YES; // enable button here
}
}
I know this is relatively old, but I wanna pitch in another idea. I've just implemented this using the UITextFieldTextDidChangeNotification.
Register for the notification:
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("textFieldDidChange:"), name: "UITextFieldTextDidChangeNotification", object: nil)
Add the method for handling the notification.
Set the enabled property of the button to true only if it's true that all of your text fields are not empty.
This wouldn't be a great solution with 20 text fields, but for 2 - 5 it's fine.
func textFieldDidChange(notification: NSNotification) {
self.button.enabled = self.firstField.text != "" && self.secondField.text != ""
}
That method gets called every time a textfield's content changes, so the button responds in real time.
I would approach this in a slightly different way.
Instead of going through the muck of enabling/disabling the UIButton, I would let the UIButton be enabled all along and let it's targeted action method decide what to do.
Example:
//Sign Up button method
-(IBAction)btnSignUp:(UIButton *)sender
{
//create a local array of the monitored textFields that should NOT be empty
NSArray *arrTextFields = #[txtF1,txtF2,txtF3,txtF4];
//helps quicken the process by using fast-enumeration as so:
for (UITextField *txtFCurrent in arrTextFields) {
if ([[txtFCurrent.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""]) {
NSLog(#"%# found to be empty",txtFCurrent);
//help direct the user to fill it
//maybe after showing an alert but anyways...
[txtFCurrent becomeFirstResponder];
//don't proceed with the main button logic
//since a required textField is empty
return;
}
}
//else...
NSLog(#"All textfields are go... Proceed with the sign up request");
//...
}
I am trying to save the order in which the buttons are pressed, and then replay that order and run the actions assigned to the buttons in the order they were originally pressed? Can anyone please help me with this?
Each UIControl element has a tag which you can use to be able to identify between the various buttons that are going to be tapped. As each button is tapped, the method (selector) associated with that button will be called (you can even have a single selector be called for all the buttons and differentiate between them via their tags).
As each button is tapped, keep track of which button is tapped by adding the tag of each button to a queue (or in Objective-C: NSMutableArray). Then to replay the actions you can merely read the tag values from the queue and call the corresponding selector.
An example to illustrate:
#property (nonatomic, strong) NSMutableArray *taskArray;
// in your init or viewDidLoad:
_taskArray = [NSMutableArray new];
// in the selector that is called by *all* buttons
-(IBAction) buttonTapped:(id)sender {
[_taskArray addObject:[NSNumber numberWithInteger:sender.tag]];
[self executeActionWithTag:sender.tag];
}
-(void) executeActionWithTag:(NSUInteger)tag {
if(tag == 1) {
// perform specific action 1 ...
} else if (tag == 2) {
// perform specific action 2 ...
}
// ...
}
-(void) replayButtonActions {
for (NSNumber *tag in _taskArray) {
[self executeActionWithTag:[tag integerValue]];
}
}
Im creating an app and one part of it has a tap counter in it.
The UI consists of a button which is pressed for counting, a reset button and a label which displays the amount of taps. The problem is that I want the iDevice to vibrate or make a sound after a specific amount of taps and then end there so the counter label doesn't react to the button anymore.
Here is my code so far:
.h
#interface TapsViewController : UIViewController {
int counter;
IBOutlet UILabel *count;
}
-(IBAction)plus;
-(IBAction)reset;
#end
.m
- (void)viewDidLoad {
counter=0;
count.text = #"Start";
}
-(IBAction)plus{
counter=counter + 1;
count.text = [NSString stringWithFormat:#"%i", counter];
}
-(IBAction)reset{
counter=0;
count.text = [NSString stringWithFormat:#"Start"];
}
How do I have the app vibrate or make a sound when the counter reaches a predetermined value?
Thank you for your help!
well to make it stop responding to the taps, just do an if statement
For example,f if you want it to stop after 5 taps.
-(IBAction)plus{
if (counter < 4) {
//just a tip, counter++; does the same thing as counter += 1; which does the same thing as counter = counter+1;
counter++;
}
else if (counter == 4) {
//after four taps, counter will equal 4, so this part will be called on the 5th tap.
counter++;
//play your sound or do your vibrate here
}
count.text = [NSString stringWithFormat:#"%i",counter];
}
To do the vibrate, look at Wain's answer. To play a sound, check out AVAudioPlayer.
Create an outlet to the button and disable it when the count limit is reached (so it won't respond to touches any more). Then enable it again when you reset.
To vibrate:
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
now i have a textField.
and i enter some words,the keyboard will appear.
when i pressed the keyboard "done",the keyboard will disappear. (i have finished this function)
but next,
i want to insert data using core data framework when the user pressed the button "done"
so,how to solve this problem?
i know how to insert data using core data,so you do not need to tell me how to insert the data.
i am using this code to disappear keyboard.
-(BOOL)textFieldShouldReturn:(UITextField *)theTextField {
[txtName resignFirstResponder];
return YES;
}
thanks everybody
In the example code, I have 3 UITextField. You can process your update after we reach the last field
// I the tag property to indicate which field I am on during runtime
enum {
Line1Tag = 50,
Line2Tag,
Line3Tag
};
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// The user has pressed the "Return Key"
// Which I have set to "Next" for first two lines
// and "Done" for the last line, so jump to the next text field
NSLog(#"\"Return\" key pressed.");
// based on which text field we are in jump to the next
if (textField.tag == Line3Tag)
// We have reach the last line so hide keyboard
[textField resignFirstResponder];
// this is where you can perform Core Data updates if you like
else {
int nextTag = textField.tag + 1;
UIView *nextField = [self.view viewWithTag:nextTag];
[nextField becomeFirstResponder];
// Once the next text field is the first responder
// I need to make sure the user can see it
[self makeActiveTextFieldVisible];
}
return NO;
}