I have a UITextView that displays a value (ex. "32039"). Frequently in my app I change the value of that number, but want to animate the increase or decrease in value. The animation I have in mind is something like this. I've seen this question but the only animations possible using the method described in the answers are those like fade in/out, move in from left/right/down/up, and reveal/push. Is there a UIKit or Core Animation implementation of this animation, or even an implementation in a 3rd party library, or should I roll my own?
// Something like this would work
#property (nonatomic, strong) UILabel *testLabel;
#property (nonatomic, strong) NSTimer *timer;
#property (nonatomic, assign) NSUInteger counter;
- (void)viewDidLoad
{
[super viewDidLoad];
self.testLabel = [[UILabel alloc] initWithFrame:CGRectMake(50.0f, 100.0f, 80.0f, 25.0f)];
self.testLabel.text = #"44";
[self.view addSubview:self.testLabel];
self.timer = [NSTimer timerWithTimeInterval:.5 target:self selector:#selector(changeLabelText) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
[self.timer fire];
}
- (void)changeLabelText {
self.counter++;
if (self.counter == 100000) {
[self.timer invalidate];
}
self.testLabel.text = [NSString stringWithFormat:#"%d", (44 + self.counter)];
}
Related
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:
I want this progress view to basically "reset" when its done.
Tried to reset the count to 0 and it does reset but for each reset the timer just becomes faster and faster.
.h
#property (nonatomic, strong) NSTimer *myTimer;
#property (weak, nonatomic) IBOutlet UILabel *progressLabel;
.m
- (void)updateUI:(NSTimer *)timer
{
static int count = 0; count++;
if (count <=100)
{
self.progressView.progress = (float)count/100.0f;
}
else
{
self.myTimer = nil;
[self.myTimer invalidate];
// shoot method for next question
count = 0;
self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
self.progressView.center = self.view.center;
[self.view addSubview:self.progressView];
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(updateUI:) userInfo:nil repeats:true];
}
}
You need to invalidate the timer before you set it to nil. As of now, your call to invalidate is a no-op. This means you keep adding more and more active timers.
Right now here is the code I'm using. It only updates when the button is pressed and is the average rather than instantaneous.
-(IBAction)button:(id)sender {
[self incrementTapCount];
NSMutableString *aString = [NSMutableString stringWithFormat:#"%.2f", averageTapsPerSecond];
[aString appendFormat:#"%s", " per second"];
current.text = aString;
}
- (void)incrementTapCount
{
tapCountInPastSecond++;
}
- (void)timerActions
{
secondsElapsed = secondsElapsed + .1;
averageTapsPerSecond = (averageTapsPerSecond*(secondsElapsed-.1) +tapCountInPastSecond) / secondsElapsed ;
tapCountInPastSecond = 0;
}
On the view did load...
[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:#selector(timerActions) userInfo:Nil repeats:YES];
I'm trying to get it to update without pressing the button, and not be the average speed, rather the speed at that moment.
Your timer fires every .1 second and you want to keep a "sliding" total of the taps in the last second. I would suggest an array of 10 integers. Each time the timer ticks you can add the most recent tap count to the end of the array and subtract the oldest.
#property (assign) NSInteger runningTotal;
#property (assign) NSInteger tapsInLastSample;
#property (strong,nonatomic) NSMutableArray *tapHistory;
-(void) viewDidLoad {
[super viewDidLoad];
self.runningTotal=0;
self.tapHistory=[NSMutableArray arrayWithCapacity:11];
[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:#selector(timerActions) userInfo:Nil repeats:YES];
}
-(IBAction)button:(id)sender {
self.tapsInLastSample++;
}
- (void)timerActions {
self.runningTotal+=self.tapsInLastSample;
[self.tapHistory addObject:[NSNumber numberWithInteger:self.tapsInLastSample]];
if (self.tapHistory.count >10) {
self.runningTotal-=[self.tapHistory[0] integerValue];
[self.tapHistory removeObjectAtIndex:0];
}
current.text=[NSString stringWithFormat:#"Taps in last second=%ld",(long)self.runningTotal];
self.tapsInLastSample=0;
}
I'm new to coding and I'm currently making a guide/reference app (My first app).
I've been using the interface builder to do most of the work. I know I need to use code soon but for now I enjoy learning with IB.
Here's my question: I have a view that has a lot of HD pictures, it takes 4-5 seconds to load until I can scroll the page smoothly. I want to add a progress view bar (between a UITableView and the navigation bar) that show a 5 seconds progress in order to let the user know that its still loading(I know about the activity indicator but the progress view bar looks nicer and seems easier to use).
Can someone guide me through all the steps in order to make a progress view bar act as a 5 seconds timer?
Let's implement as this way for 5 min progressView,
In .h file,
NSTimer * timer;
UIProgressView * progView;
float duration;
In .m file
- (void)viewDidLoad
{
[super viewDidLoad];
progView = [[UIProgressView alloc] initWithFrame:CGRectMake(10.0, 0.0, 300.0, 10.0)];
[self.view addSubview:progView];
timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(updateProgress) userInfo:nil repeats:YES];;
}
-(void)updateProgress
{
duration += 0.1;
progView.progress = (duration/5.0); // here 5.0 indicates your required time duration
if (progView.progress == 1)
{
[timer invalidate];
timer = nil;
}
}
Thanks!
This should get you started:
#property (nonatomic, strong) NSTimer *progressTimer;
#property (nonatomic, assign) CGFloat progress;
#property (nonatomic, strong) UIProgressView *progressView;
- (void)yourMethod
{
if (!self.progressView)
{
self.progressView = [[UIProgressView alloc]initWithFrame:CGRectMake(0, 64, 320, 2)];
self.progressView.progressTintColor = [UIColor greenColor];
[self.navigationController.navigationBar.superview insertSubview:self.progressView belowSubview:self.navigationController.navigationBar];
}
else
{
self.progressView.hidden = NO;
}
self.progressTimer = [NSTimer timerWithTimeInterval:0.1 target:self selector:#selector(updateProgressView) userInfo:nil repeats:YES];
NSTimer *stopProgressTimer = [NSTimer timerWithTimeInterval:5.0 target:self selector:#selector(stopProgressView) userInfo:nil repeats:NO];
[stopProgressTimer fire];
}
- (void)stopProgressView
{
[self.progressTimer invalidate];
self.progress = 0.0f;
self.progressView.hidden = YES;
self.progressView.progress = 0.0f;
}
- (void)updateProgressView
{
self.progress = (self.progress + 0.1f) / 5;
self.progressView.progress = self.progress;
}
I have something like this
http://www.allappsdevelopers.com/images/TopicImages/TableView%20in%20iphone/index.png
And i also want to show something like MBProgressHud while scrolling by these letters. I saw in some apps that when u scrolling by indexes, the letter is showing in black rounded view at the center of the window.
Note: not when scrolling manually, but only when scrolling by using indexes.
Can i somehow detect start dragging on this panel and end dragging? Or is there any other way to implement it?
Made my own solution:
#property (retain, nonatomic) MBProgressHUD *letterBar;
#property (retain, nonatomic) NSTimer *letterBarTimer;
self.letterBar = [[MBProgressHUD alloc] initWithView:self.view];
[self.letterBar setUserInteractionEnabled:NO];
[self.letterBar setMode:MBProgressHUDModeText];
[self.view addSubview:self.letterBar];
-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
[self.letterBarTimer invalidate];
[self.letterBar setLabelText:title];
[self.letterBar show:YES];
self.letterBarTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(hideLetterBar) userInfo:nil repeats:NO];
return index;
}
-(void)hideLetterBar {
[self.letterBar hide:YES];
}