I have the following code that works for a Timer view.
The problem is, when I change segments, while the timer is already running, the label resets, but the button text still stay's stop, I need it to stay "start" instead. I tried doing it manually by doing self.timer.titleLabel.text = #"Start"; but for some reason it shows as "S...t" instead of "Start".
- (IBAction)startStop:(UIButton *)sender
{
if ( self.myTimer )
{
[self.myTimer invalidate];
self.myTimer = nil;
[sender setTitle:#"Start" forState:UIControlStateNormal];
}
else
{
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(handleTimer:) userInfo:nil repeats:YES];
[sender setTitle:#"Stop" forState:UIControlStateNormal];
}
}
- (void)handleTimer:(NSTimer *)timer
{
self.counter--;
self.timerLabel.text = [NSString stringWithFormat:#"%ld", self.counter];
if ( self.counter <= 0 ){
[self.myTimer invalidate];
self.myTimer = nil;
}
}
- (IBAction)reset:(id)sender
{
self.counter = self.counterSegment;
self.timerLabel.text = timerCount;
}
- (void)segmentedControl:(SVSegmentedControl*)segmentedControl didSelectIndex:(NSUInteger)index
{
if ( self.myTimer )
{
[self.myTimer invalidate];
self.myTimer = nil;
self.timer.titleLabel.text = #"Start";
}
if (index == 0)
{
NSLog(#"15 sec");
self.timerCount = #"15";
self.counterSegment = 15;
}
else if (index == 1)
{
NSLog(#"30 sec");
self.timerCount = #"30";
self.counterSegment = 30;
}
else if (index == 2)
{
NSLog(#"60 sec");
self.timerCount = #"60";
self.counterSegment = 60;
}
self.counter = self.counterSegment;
self.timerLabel.text = timerCount;
}
If the button label reads "S...t" instead of "Start", then you need to make the font smaller or invoke adjustsFontSizeToFitWidth, e.g.
button.titleLabel.font = [UIFont systemFontOfSize: 10];
or
button.titleLabel.adjustsFontSizeToFitWidth = YES;
Related
When repeat button is hit for the first time then it should run infinite times and when it is hit for second time then it should not repeat audio rather it should stop looping. . Below is the code it works very well for the first time but when it is pressed again it is not stopping looping.
BOOL isFirstTime;
#interface English : UIViewController <UITextViewDelegate, ADBannerViewDelegate, UIScrollViewDelegate,
-(void) RepeatAction:(id)sender{
if(isFirstTime == YES){
player.numberOfLoops = -1;
} else {
player.numberOfLoops = 0;
}
}
- (void)playAction:(id)sender
{
if([player isPlaying])
{
[sender setImage:[UIImage imageNamed:#"1play.png"] forState:UIControlStateSelected];
[player pause];
}else{
[sender setImage:[UIImage imageNamed:#"audiopause.png"] forState:UIControlStateNormal];
[player play];
slidertimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:#selector(updateProgressBar:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:slidertimer forMode:NSRunLoopCommonModes];
timer = slidertimer;
}}
Thanks for help.
-(void) RepeatAction:(id)sender{
if(isFirstTime){ // even here you need not to compare with == YES
player.numberOfLoops = -1;
isFirstTime = NO;
} else {
player.numberOfLoops = 0;
isFirstTime = YES;
}
}
good day.. I have this code.. and this two is for actionAnimating Button and stopAnimating Button..I just want to know if how to make those two button integrate in ONE button.. for example.. I click the button then it animates.. when I click again that actionAnimating Button, i want to cancel/stop the animation at the same time i want to play/animate again.. in short i want to cancel the animation when i click again the actionAnimating button..
-(void)flowerAnimationSequence//START ANIMATION
{
MotherView.alpha = 0;
flower.alpha = 0;
[animationContainer1 removeFromSuperview];
actselected = YES;
NSLog(#"start");
if (((sequenceAnimateCounter == 0) || (sequenceAnimateCounter==1)) && (actselected = YES))
{
aImageViewSlideShow = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
aImageViewSlideShow.tag = 171;
[self.view addSubview:aImageViewSlideShow];
}
if (sequenceAnimateCounter < 183)
{
timer = [NSTimer scheduledTimerWithTimeInterval:0.035 target:self selector:#selector(flowerAnimationSequence) userInfo:nil repeats:NO];
}
else if (sequenceAnimateCounter ==183)
{
aImageView = (UIImageView *)[self.view viewWithTag:171];
NSLog(#"done");
actselected = NO;
sequenceAnimateCounter = 0;
[aImageView removeFromSuperview];
aImageView = nil;
[self DefaultPosition];
}
aImageView = (UIImageView *)[self.view viewWithTag:171];
NSString *aStrNumber = [NSString stringWithFormat:#"%i",sequenceAnimateCounter];
NSString *aBundlePath = [[NSBundle mainBundle]bundlePath];
NSString *aImagePath = [NSString stringWithFormat:#"%#/sapatos_%#.png",aBundlePath,aStrNumber];
[aImageView setImage:[UIImage imageWithContentsOfFile:aImagePath]];
[self.view bringSubviewToFront: aImageView];
sequenceAnimateCounter = sequenceAnimateCounter+1;
if (sequenceAnimateCounter == 1)
{
[aImageView removeFromSuperview];
}
}
-(void)stopanim//STOP BUTTON
{
[timer invalidate];
sequenceAnimateCounter =0;
NSLog(#"stop");
[aImageView removeFromSuperview];
}
thanks in advance!
Hm...
you want to start/stop in one button?
BOOL isAnimating = NO;
- (void)startStopAnimating
{
if (!isAnimating) {
isAnimating = YES
// start animation
} else {
isAnimating = NO;
// stop animation
}
}
I want to make a "downloading" uilabel whose label text will change dynamically when I call the method "updating":
self.checkingArray = [NSArray arrayWithObjects:#"download", #"download.", #"download..", #"download...",
nil];
- (void) updating
{
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(changeText) userInfo:nil repeats:YES];
}
- (void) changeText
{
checkLabel.text = [self.checkingArray objectAtIndex:curCheckingState];
self.curCheckingState++;
if (self.curCheckingState >= 4) {
self.curCheckingState = 0;
}
But the label text stay with the text "download...", I want to know how to achieve my purpose?
Implement this:
- (void) updating
{
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(changeText) userInfo:nil repeats:YES];
}
- (void) changeText
{
static unsigned char state = 0;
checkLabel.text = [self.checkingArray objectAtIndex:state];
if(state < 3) state++;
else state = 0;
}
Do this:
self.checkingArray = [NSArray arrayWithObjects:#"download", #"download.", #"download..", #"download...",
nil];
self.curCheckingState = 0;
- (void) updating
{
//change timer time interval if needed
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(changeText) userInfo:nil repeats:YES];
}
- (void) changeText
{
checkLabel.text = [self.checkingArray objectAtIndex:self.curCheckingState];
if (self.curCheckingState == 3) //depending on [array count]-1
{
self.curCheckingState = 0;
}
else
{
self.curCheckingState++;
}
}
I have this code in LongTapGestureRecognizer for autoscrolling a view:
-(void) longPressDetectedgesture:
(UILongPressGestureRecognizer*)recognizer
{
_btnautoscrollstop.hidden = NO;
_btnautoscroll.hidden = YES;
// if (autoscrollTimer == nil) {
autoscrollTimer = [NSTimer
scheduledTimerWithTimeInterval:(55.0/1000.0)
target:self
selector:#selector(autoscrollTimerFired:)
userInfo:nil
repeats:YES];
}
- (void)autoscrollTimerFired:(NSTimer*)timer {
CGPoint scrollPoint = self.table.contentOffset;
scrollPoint = CGPointMake(scrollPoint.x, scrollPoint.y + 1);
[self.table setContentOffset:scrollPoint animated:NO];
}
It works perfect for me, but my need is, the autoscrooling must stop when the user taps the screen for Longgesture for the second time and vise versa. How to stop this, when the user taps for a second time.
It looks like you're almost there. You probably want something like this:
if (recogniser.state == UIGestureRecognizerStateBegan) {
if (autoscrollTimer == nil) {
autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:(55.0/1000.0)
target:self
selector:#selector(autoscrollTimerFired:)
userInfo:nil
repeats:YES];
} else {
[autoscrollTimer invalidate];
autoscrollTimer = nil;
}
}
What i usually do is declare a global BOOL Alter; and initialize it Alter = NO; in viewDidLoad (or any other method) then
-(void) longPressDetectedgesture:(UILongPressGestureRecognizer*)recognizer
{
if(Alter)
{
Alter = NO;
[autoscrollTimer inValidate];
}
else
{
Alter = YES;
_btnautoscrollstop.hidden = NO;
_btnautoscroll.hidden = YES;
// if (autoscrollTimer == nil) {
autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:(55.0/1000.0)
target:self
selector:#selector(autoscrollTimerFired:)
userInfo:nil
repeats:YES];
}
}
create a BOOL called shouldFireTimer in viewDidLoad or similar and update it's value each time you detect a longpress
-(void) longPressDetectedgesture: (UILongPressGestureRecognizer*)recognizer {
_btnautoscrollstop.hidden = NO;
_btnautoscroll.hidden = YES;
if ( shouldFireTimer ) {
[autoscrollTimer invalidate];
autoscrollTimer = nil;
} else {
autoscrollTimer = [NSTimer
scheduledTimerWithTimeInterval:(55.0/1000.0)
target:self
selector:#selector(autoscrollTimerFired:)
userInfo:nil
repeats:YES];
}
shouldFireTimer = !shouldFireTimer;
}
- (void)autoscrollTimerFired:(NSTimer*)timer {
CGPoint scrollPoint = self.table.contentOffset;
scrollPoint = CGPointMake(scrollPoint.x, scrollPoint.y + 1);
[self.table setContentOffset:scrollPoint animated:NO];
}
or like Matt says above maybe just check nil status instead of using a BOOL. I suggest using a BOOL as you maybe firing autoscrollTimerFired in other circumstances too (from a button for example) i.e. it might not be nil when you want to call it.
I have set up an animation in Xcode using an NSTimer, and It kept repeating over and over, so i used this command:
else if(gordon.image == pigImage11)
[animationTimer invalidate];
So, when gordon (a UIImageView) image is set to pigImage11, The timer invalidates, this gave the desired effect of stopping the animation constantly repeating, But stopped the timer being used again, so how would I make the timer usable again, But have it invalidate itself on that frame?
For the sake of further clarification here's my entire code:
- (IBAction)startClick:(id)sender{
animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.00/30.00) target:self selector:#selector(tick) userInfo:nil repeats:YES];
}
- (void)tick{
[self animatePig];
}
- (void)animatePig{
UIImage *pigImage1=[UIImage imageNamed:#"gordonapple0004.png"];
UIImage *pigImage2=[UIImage imageNamed:#"gordonapple0005.png"];
UIImage *pigImage3=[UIImage imageNamed:#"gordonapple0006.png"];
UIImage *pigImage4=[UIImage imageNamed:#"gordonapple0007.png"];
UIImage *pigImage5=[UIImage imageNamed:#"gordonapple0008.png"];
UIImage *pigImage6=[UIImage imageNamed:#"gordonapple0009.png"];
UIImage *pigImage7=[UIImage imageNamed:#"gordonapple0010.png"];
UIImage *pigImage8=[UIImage imageNamed:#"gordonapple0011.png"];
UIImage *pigImage9=[UIImage imageNamed:#"gordonapple0012.png"];
UIImage *pigImage10=[UIImage imageNamed:#"gordonapple0013.png"];
UIImage *pigImage11=[UIImage imageNamed:#"gordonapple0014.png"];
UIImage *pigImage12=[UIImage imageNamed:#"gordonapple0015.png"];
UIImage *pigImage13=[UIImage imageNamed:#"gordonapple0016.png"];
if(gordon.image == pigImage1)
gordon.image = pigImage2;
else if(gordon.image == pigImage2)
gordon.image = pigImage3;
else if(gordon.image == pigImage3)
gordon.image = pigImage4;
else if(gordon.image == pigImage4)
gordon.image = pigImage5;
else if(gordon.image == pigImage5)
gordon.image = pigImage6;
else if(gordon.image == pigImage6)
gordon.image = pigImage7;
else if(gordon.image == pigImage7)
gordon.image = pigImage8;
else if(gordon.image == pigImage8)
gordon.image = pigImage9;
else if(gordon.image == pigImage9)
gordon.image = pigImage10;
else if(gordon.image == pigImage10)
gordon.image = pigImage11;
else if(gordon.image == pigImage11)
[animationTimer invalidate];
else
gordon.image = pigImage1;
}
- (void)stopTimer
{
[animationTimer invalidate];
[animationTimer release];
}
You can reuse a timer like this:
- (void) startTimer {
if ( myTimer == nil ) {
myTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0f
target: self
selector: #selector(myTimerAction:)
userInfo: nil
repeats: NO];
}
}
- (void) stopTimer {
if ( myTimer || [myTimer isValid])
{
[myTimer invalidate];
myTimer = nil;
}
}
How about not invalidating the timer and just setting a "don't animate" flag instead?
[[NSRunLoop currentRunLoop] addTimer:animationTimer
forMode:NSDefaultRunLoopMode];
But you must not release the timer after invalidating, of course.
Why not use UIImageView's built in animation:
UIImageView* gordonView = [[UIImage alloc]init];
gordonview.animationImages = [NSArray arrayWithObjects: pigImage1, pigimage2, etc., nil];
gordonView.animationDuration = 0.5f; // about 30fps with your 13 images.
//Set gordon's frame here
[gordonView startAnimating];
Disclosure, I typed this into SO, not Xcode I'm certain it will not compile but at least you know what to look for in the SDK.