How to have two buttons change title and do two different functions? - ios

I'm using Objective-C to make a stopwatch. I already have a basic stop watch with 3 buttons: Start, Stop and reset. Here is my code for viewcontroller.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)Start:(id)start
{
Timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(addingthetime) userInfo:nil repeats:YES];
}
-(IBAction)Stop:(id)sender
{
[Timer invalidate];
}
-(IBAction)Restart:(id)sender
{
[Timer invalidate];
addingtheTime = 0;
Label.text = [NSString stringWithFormat:#"0.00"];
}
-(void)addingthetime
{
addingtheTime = addingtheTime + 0.01;
Label.text = [NSString stringWithFormat:#"%.2f", addingtheTime];
}
#end
And here is my code for viewcontroller.h:
#import <UIKit/UIKit.h>
float addingtheTime;
#interface ViewController : UIViewController
{
IBOutlet UILabel *Label;
NSTimer *Timer;
}
#end
So my question is how do I make the Start button do the following once clicked:
Start the timer
Change the title to stop
(Click the same button again)
Stop the timer
Change the title to start
So the aim is to have only one button which starts and stops the timer but please I want the title to change as well.
Don't worry about the reset button as I want that to remain by itself.
PS. Please explain things clearly because I find it really hard to understand some things and I am a beginner so try and keep it fairly simple thanks, and sorry if the question isn't clear.

You can use button.tag property to achieve this. By Default the button.tag property have 0. So assume that 0 is a state when timer is Not started and 1 is the state when timer is started. You can manipulate .tag property according to your custom logic.
-(IBAction)Start:(id)start
{
UIButton *button = (UIButton *)start;
if (button.tag == 0){
button.tag = 1;
[button setTitle:#"Stop" forControlState:UIControlStateNormal];
Timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(addingthetime) userInfo:nil repeats:YES];
}else {
button.tag = 0;
[button setTitle:#"Stop" forControlState:UIControlStateNormal];
//Invoke your method to stop Timer.
}
}

In the ViewController.h:
#import <UIKit/UIKit.h>
float addingtheTime;
#interface ViewController : UIViewController
{
IBOutlet UILabel *Label;
NSTimer *Timer;
}
#end
In the ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)addingthetime
{
addingtheTime = addingtheTime + 0.01;
Label.text = [NSString stringWithFormat:#"%.2f", addingtheTime];
}
- (IBAction)startOrStopAction:(UIButton *)sender {
// stop
if ([sender.titleLabel.text isEqualToString:#"stop"]) {
[Timer setFireDate:[NSDate distantFuture]];
[sender setTitle:#"start" forState:UIControlStateNormal];
}
// start
else {
if (!Timer) {
Timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(addingthetime) userInfo:nil repeats:YES];
}else {
[Timer setFireDate:[NSDate date]];
}
[sender setTitle:#"stop" forState:UIControlStateNormal];
}
}
#end
The result:
In iPhone:
In iPad:

Related

Countdown timer that stops and reset on 0

Got an issue with my countdown timer who don't want to countdown from 60 and reset when 0 is reached. At the moment it just sets its label 0 and start counting down to -1, 2-... How do I get it to start from 60 on iOS in xcode?
.m file
#import "ViewController.h"
#interface ViewController ()
{
int timeTick;
NSTimer *timer;
}
#end
#implementation ViewController
- (IBAction)stopStartBtn:(id)sender {
[timer invalidate];
timeTick = 3;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
}
-(void)myTicker{
timeTick--;
NSString *timeString =[[NSString alloc] initWithFormat:#"%d", timeTick];
self.display.text = timeString;
if(timer >= 0){
[timer invalidate];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
timeTick = 3;
}
#end
.h File
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *display;
- (IBAction)stopStartBtn:(id)sender;
#end
Your code currently starts the timer at 0, decrements it, and then checks it it has reached 60. Obviously that won't happen.
If you want to start at 60 and stop at 0 then you need to set timeTick to 60 in viewDidLoad and check for a value of 0 in myTicker.
And don't forget to call [super viewDidLoad]; in your viewDidLoad method.
You also need to fix your check to see if you've reached zero. Right now you are looking at the timer pointer instead of timeTick integer.
Change:
if(timer >= 0){
[timer invalidate];
}
to:
if (timeTick <= 0) {
[timer invalidate];
}
You are also never setting your timer instance variable. You actually set a local variable of the same name.
Change:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
to:
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
#interface Ovning1 ()
{
int timeTick;
NSTimer *timer;
}
#end
#implementation Ovning1
- (IBAction)stopStartBtn:(id)sender {
[timer invalidate];
timeTick = 60;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
}
-(void)myTicker{
timeTick--;
NSString *timeString =[[NSString alloc] initWithFormat:#"%d", timeTick];
self.display.text = timeString;
if(timeTick <= 0){
[timer invalidate];
}
}

Xcode (Objective C) - Error regarding interface?

I'm a beginner to Xcode nd Objective-C! I'm making an ios app which is basically a stop watch. The idea is only to have two buttons. One to reset the stopwatch and the other to start and stop the clock. (Basically, you click the start button which then turns into a stop button which when clicked will stop the stopwatch. The problem is I have two errors which are the same and read the following: (I don't know how to fix them which is the question!)
No visible #interface fro 'UIButton' declares the selector 'setTitle:forControlState:'
This has come up twice at two points! Point one:
[button setTitle:#"Start" forControlState:UIControlStateNormal];
And point two...
[button setTitle:#"Stop" forControlState:UIControlStateNormal];
Here is my code for VeiwController.h:
//
#import <UIKit/UIKit.h>
float addingtheTime;
#interface ViewController : UIViewController
{
IBOutlet UILabel *Label;
NSTimer *Timer;
}
#end
Here is my code for ViewController.m
//
#import "ViewController.h"
#interface ViewController ()\
#end
#implementation ViewController
-(IBAction)Start:(id)start
{
UIButton *button = (UIButton *)start;
if (button.tag == 0){
button.tag = 1;
[button setTitle:#"Start" forControlState:UIControlStateNormal];
Timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(addingthetime) userInfo:nil repeats:YES];
}else {
button.tag = 0;
[button setTitle:#"Stop" forControlState:UIControlStateNormal];
//Invoke your method to stop Timer.
}
}
-(IBAction)Restart:(id)sender
{
[Timer invalidate];
addingtheTime = 0;
Label.text = [NSString stringWithFormat:#"0.00"];
}
-(void)addingthetime
{
addingtheTime = addingtheTime + 0.01;
Label.text = [NSString stringWithFormat:#"%.2f", addingtheTime];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Please note I am a beginner so please explain as much as you can and thanks you in advance for any help!!!
its forstate not forControlState
[button setTitle:#"start" forState:UIControlStateNormal];
[button setTitle:#"stop" forState:UIControlStateNormal];

iOS UISwitch keep sending message every 4 second

I have a chatting app that has a uiswitch. If the Switch button is on, I want the app to send "hi" continuously every 3 seconds even the app is in background mode. I know that I can use NSTimer, but I don't really know how to implement that in this code(This is my first time to develop iOS app). Please help me with this.
My code is :
// Allocate, initialize, and add the automatic button.
_AutomaticSend = [[UISwitch alloc] initWithFrame:CGRectMake([self width] - 50.0, textAreaY + Center(160.0, textAreaHeight), 50.0, 50.0)];
[_AutomaticSend addTarget:self action:#selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
and
// Switch action
//NSUInteger counter = 0;
- (void)changeSwitch:(id)sender{
if([sender isOn]){
for (int a=1; a<=300; a++)
{
//[self performSelector:#selector(changeSwitch:) withObject:_textField afterDelay:70.0];
[sender setOn:YES animated:YES];
[_textField setText:#"hi"];
NSString * text = [_textField text];
// Update status.
[[TSNAppContext singleton] updateStatus:text];
// Add the status to the bubble.
[self appendLocalPeerTableViewCellWithMessage:text];
}
// NSLog(#"Switch is ON");
} else{
NSLog(#"Switch is OFF");
}
}
Now, the app is showing all "hi" after all 300 "hi" is ready to show. But I want it to send it one by one continuously.
Define a NSTimer instance and a counter in your view controller:
#property (nonatomic, strong) NSTimer *timer;
#property (nonatomic, assign) NSInteger counter;
Implement the method when timer is fired:
- (void)timerAction:(id)sender {
[_textField setText:#"hi"];
NSString * text = [_textField text];
// Update status.
[[TSNAppContext singleton] updateStatus:text];
// Add the status to the bubble.
[self appendLocalPeerTableViewCellWithMessage:text];
// stop the timer after sending for 300 times
self.counter += 1;
if (self.counter >= 300) {
[self.timer invalidate];
self.timer = nil;
}
}
Starts the timer when switch is on:
- (void)changeSwitch:(id)sender{
if ([sender isOn]) {
self.counter = 0;
self.timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(timerAction:) userInfo:nil repeats:YES];
} else {
// kill the timer when switch is off
[self.timer invalidate];
self.timer = nil;
}
}
However, you can't make the timer to continue working indefinitely after your app is entering background (with some exceptions: VoIP, GPS applications, etc.). Please refer to the official document Background Execution.
//Nstimer *timer in .h
In your UISwitch Method Write like this
- (void)changeSwitch:(id)sender{
if([sender isOn]){
timer=[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(targetMethod)
userInfo:nil
repeats:NO];
}
else
{
[timer invalidate];
}
}
targetMethod Like this
-(void)targetMethod
{
[sender setOn:YES animated:YES];
[_textField setText:#"hi"];
NSString * text = [_textField text];
// Update status.
[[TSNAppContext singleton] updateStatus:text];
// Add the status to the bubble.
[self appendLocalPeerTableViewCellWithMessage:text];
}
Use NSTimer: Documentation of NSTimer
Declare property of NSTimer in .h file:
#property (retain,nonatomic) NSTimer *myTimer;
- (void)changeSwitch:(id)sender
{
if([sender isOn]){
myTimer = [NSTimer scheduledTimerWithTimeInterval: 4 target: self
selector: #selector(AddMessage:) userInfo: nil repeats: YES];
} else{
[self.timer invalidate];
}
}
After each 4 second, timer will call the below function:
-(void) AddMessage:(NSTimer*) timer
{
//Add Message
}

IBAction disabling not working

If the user keeps clicking on button1 one or two , progress2.progress keeps increasing/decreasing on each click and progress1.progress keeps the same value until the user stops clicking. And in case he will surely lose , if he also keeps clicking nothing happens until he stops clicking. I don't want it to be that way since I want to hide/disable the buttons as soon as it's confirmed that he's losing to fix this issue. Any way to fix that?
Here is my .m :
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (BOOL)prefersStatusBarHidden { return YES; }
- (void)viewDidLoad
{
progress1.progress=arc4random() % 11 * 0.1;
count1=0;
count2=0;
label1.hidden = NO;
gameOver.hidden = YES;
score=0;
[super viewDidLoad];
;
}
// Do any additional setup after loading the view, typically from a nib.
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)regulator{
if(timer1)
{
[timer1 invalidate];
timer1 = nil;
}
if(timer4)
{
[timer4 invalidate];
timer4 = nil;
}
timer4 =[NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:#selector(conditioner) userInfo:nil repeats:YES];
;}
-(void)conditioner {
if (fabs(progress2.progress-progress1.progress)<=0.25 )
{
score=score+1;
scorenumber.text= [NSString stringWithFormat:#"%i",score];
[self newGame];
;
} else{
stop1=YES;
stop2=YES;
gameOver.hidden=NO;
stick.hidden=YES;
bg.hidden=YES;
progress1.hidden=YES;
progress2.hidden=YES;
supply.hidden=YES;
demand.hidden=YES;
}}
-(void)newGame{
progress1.progress=arc4random() % 11 * 0.1;}
- (IBAction)start:(UIButton *)sender {
progress2.progress=arc4random() % 11 * 0.1;
if(timer4)
{
[timer4 invalidate];
timer4 = nil;
timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(regulator) userInfo:nil repeats:YES];
[self regulator];
stop1=NO;
stop2=NO;
label1.hidden=YES;
UIButton *button1 = (UIButton *)sender;
button1.enabled = NO;
UIButton *button2 = (UIButton *)sender;
button2.enabled = NO;
}
- (IBAction)button1:(UIButton *)sender {
if(stop1==YES){button12.hidden = TRUE;}
progress2.progress=progress2.progress-0.05;
;
[self regulator];
count2=0;
count1 = count1 +1;
}
- (IBAction)button2:(UIButton *)sender {
[self regulator];
progress2.progress=progress2.progress+0.05;
if(stop2==YES){button22.hidden = TRUE;}
count1 =0;
count2 = count2+1;
}
#end
and my .h:
#import <UIKit/UIKit.h>
int count1;
int count2;
int score;
void *regulator;
void *newGame;
void *conditioner;
BOOL stop1;
BOOL stop2;
void *firstLaunch;
#interface ViewController : UIViewController{
IBOutlet UILabel *scorenumber;
IBOutlet UIImageView *stick;
IBOutlet UILabel *label1;
IBOutlet UIImageView *bg;
IBOutlet UILabel *supply;
IBOutlet UILabel *demand;
IBOutlet UILabel *gameOver;
IBOutlet UIProgressView *progress1;
IBOutlet UIProgressView *progress2;
IBOutlet UIButton *button12;
IBOutlet UIButton *button22;
NSTimer *timer1;
NSTimer *timer2;
NSTimer *timer3;
NSTimer *timer4;
}
- (IBAction)button1:(UIButton *)sender;
- (IBAction)button2:(UIButton *)sender;
#end
Thanks a lot for any help or information. I edited my question with the full code to give further explanation about the issue I'm facing. Regards.
This is actually a coding issue. MVC basics.
I believe you miss some understanding of things. So I'll explain:
IBAction - It's an action sent from the view to the controller.
IBOutlet - Meant for the controller to control the view.
On your code you are getting the sender (which should be read only when coding right) and you are trying to set it up. I assume you need to define a new IBOutlet to represent the button then connect it on your storyboard and then inside this function to make it enable/disabled.
Also a good practice would be to use "TRUE" and "FALSE" and not "YES/NO".
Hope this helps.
There are couple of ways you can approach this to make sure when user touches the button then it doesn't do anything.
It wasn't clear from your question so I assume on touch down of button you call (IBAction)button1. So Try
- (IBAction)button1:(UIButton *)sender
{
if(stop1==YES)
{
//game has stopped so don't do anything
}
else
{
progress2.progress=progress2.progress-0.05;
[self regulator];
}
}
If you want to hide it so that the user can't do anything try this
- (IBAction)button1:(UIButton *)sender
{
if(stop1==YES)
{
//game has stopped so hide this button
//assuming you have connected an IBOutlet to your button1
button1.hidden = YES;
}
else
{
button1.hidden = NO;
progress2.progress=progress2.progress-0.05;
[self regulator];
}
}

UILabel wont show the previous characters, only the last letter

Goal is to enumerate every character in the String. That is 'w' will appear then after 1 sec will be replaced by 'h' then 'e' then 'n'.
Problem my label only shows the last letter.
What i did:
1. drag a label and a button on the PlayViewController.
2. create the property for Label
3. create action for button
In my PlayViewController.h:
#import <UIKit/UIKit.h>
#interface PlayViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *listChar;
- (IBAction)startGame:(id)sender;
#end
In my PlayViewController.m:
#import "PlayViewController.h"
#interface PlayViewController ()
#end
#implementation PlayViewController
NSString *word;
NSTimer *myTimer;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.listChar.text = #" ";
word = #"when";
}
- (IBAction)startGame:(id)sender {
myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(listLetter:) userInfo:nil repeats:YES];
}
-(void) listLetter:(NSTimer*) myTimer {
for(int i=0; i<[word length]; i++){
unichar letter = [word characterAtIndex: i];
self.listChar.text = [NSString stringWithFormat:#"%C", letter];
}
}
#end
If you want to know about why this happning then refer #Nitin's answer, and if you want to solve in other way then just use following code
-(void) listLetter:(NSTimer*) myTimer
static int pos = 1;
self.listChar.text = [word substringToIndex:pos];
if (++pos > word.length) {
[myTimer invalidate];
}
}

Resources