I am having a problem with displaying time on UITableViewCell
unsigned long long seconds = milliseconds/1000;
unsigned long long minutes = seconds/60;
unsigned long long hours = minutes/60;
seconds -= minutes * 60;
minutes -= hours * 60;
NSString * result1 = [NSString `enter code here`stringWithFormat:#"%02lluH:%02lluM:%02lluS",hours,minutes,seconds];
self.menushowTime.text = result1;//populate cell label with time
Whenever I am reloading the table view my timer is running with 2x speed, I mean very fast. How can I prevent this from happening.
facing problem when i start scrolling tableview or reloading the tableview.?
Yes it happens, because timer is attached to NSRunLoop, so when the UI thread is busy doing animations , NSRunLoop has to halt. It finishes animations and later increments your timer. so the timer wont increase perfectly during this time.
use below one,
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
first calculate minutes, later seconds.
Change your code to below.
minutes -= hours * 60;
seconds -= minutes * 60;
Related
I am getting millisecond and i want to convert that millisecond to day,hours,minutes,second and display and want to display it in uiTableview. and i want to update that timer every second..
i had try this code using uiTableview delegate method cellForRowAtIndexPath.
NSInteger totleTime = [[[productListDataArray objectAtIndex:indexPath.row]objectForKey:#"_auction_duration"] integerValue];
totleTime = totleTime - timerValue ;
long days = (totleTime) / (60 * 60 * 24);
long hours = (totleTime - days * 60 * 60 * 24) / (60 * 60);
long minuts = (totleTime - days * 60 * 60 * 24 - hours * 60 * 60) / 60;
long seconds = (totleTime - days * 60 * 60 * 24 - hours * 60 *60 - minuts * 60);
NSLog(#"seconds : %.f minutes : %.f hours : %.f days : %.f ", seconds, minuts, hours, days);
I had used this method for call method and update tableview. but its not working so suggest me another option or tell me what i had done wrong in this code..
What I understand from your question is that you want to reload your tableView every second. First of all, let me say that it is a bad idea. If your tableView is being reloaded then the user will not be able to see anything. Having said that, you can use a timer with a certain interval that calls a method. That method can decide when to reload the tableView.
EDIT
From your last comment, I understand that you are trying to display a countdown timer in a tableview cell. For that purpose, you don't need to reload the tableview. You only have to update the datasource and reload the row that is displaying the counter. Something along these lines.
The code snippet below is in Swift 2
//Call a method named tick() every second
let timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(tick), userInfo: nil, repeats: true)
func tick() {
//DO YOUR CALCULATIONS HERE TO CALCULATE YOUR DAYS, MINUTES, etc. THEN CALL THE FOLLOWING METHOD
tblView.reloadRowsAtIndexPaths([NSIndexPath(forRow: {rowNumber}, inSection: {sectionNumber})], withRowAnimation: .None)
//ALSO MAKE SURE YOUR cellForRowAtIndexPath IS CORRECTLY SETTING THE CELL VALUES
}
Don't forget to invalidate the timer when you're finished with it
i have get solve this issues.
1.At initial i had set timer is 1 second.
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
2.Every Second Call Method and change value and reload tableview.
- (void)updateCounter:(NSTimer *)theTimer {
timerValue += 1;
[ProductListTableView reloadData];
}
3. now calculate remaining time in uitableView deleget method cellForRowAtIndexPath
NSInteger totleTime = [[[productListDataArray objectAtIndex:indexPath.row]objectForKey:#"_auction_duration"] integerValue];
totleTime = totleTime - timerValue ;
long days = (totleTime) / (60 * 60 * 24);
long hours = (totleTime - (days * 60 * 60 * 24)) / (60 * 60) ;
long minuts = (totleTime - (days * 60 * 60 * 24) - (hours * 60 * 60)) / 60;
long seconds = (totleTime - (days * 60 * 60 * 24) - (hours * 60 * 60) - (minuts * 60));
cell.saleTimeLabel.text = [NSString stringWithFormat:#"%# Sold %ld:%ld:%ld:%ld",[[productListDataArray objectAtIndex:indexPath.row]objectForKey:#"sales_qty"], days,hours,minuts,seconds];
I don't know timeValue's meanings, if timeValue assume system time. you can write a timer to reload tableView's data.
I'm optimizing the scrolling smoothness of a UITableView, but it's tough to notice subtle gains by eye. I'm looking for a straightforward way to print out the "load time" of each UITableViewCell as it appears. Is this possible?
but it's tough to notice subtle gains by eye.
Don't try. Use Instruments! That's what it's for. The Core Animation instrument will tell you the FPS when you scroll, which is exactly what you want to know here. And the Time Profiling instrument will tell you exactly where in your code the time is being spent.
Don't guess. Don't eyeball. Don't add your own timing instrumentation. Use Instruments!
You can do two things:
1: Measure execution time for - tableView:cellForRowAtIndexPath:
2: Measure execution time for - reloadData
Measuring:
- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath {
CFTimeInterval startTime = CACurrentMediaTime();
//Do your thing - dequeue, setup your cell.
CFTimeInterval endTime = CACurrentMediaTime();
NSLog(#"Cell Creation: %g s", endTime - startTime);
return cell;
}
and wherever you call reloadData()
CFTimeInterval startTime = CACurrentMediaTime();
[self.tableView reloadData];
CFTimeInterval endTime = CACurrentMediaTime();
NSLog(#"Cell Creation: %g s", endTime - startTime);
you can use the mach absolute time for the most accurate results. there is a good explanation here: https://developer.apple.com/library/mac/qa/qa1398/_index.html
example code:
uint64_t startTime = mach_absolute_time();
// do work here
uint64_t endTime = mach_absolute_time();
uint64_t elapsedTime = endTime - startTime;
mach_timebase_info_data_t sTimebaseInfo;
mach_timebase_info(&sTimebaseInfo);
uint32_t numer = sTimebaseInfo.numer;
uint32_t denom = sTimebaseInfo.denom;
uint64_t elapsedNano = (elapsedTime * numer / denom);
NSTimeInterval elapsedSeconds = elapsedNano / (CGFloat)NSEC_PER_SEC;
NSLog(#"elapsed time: %f", elapsedSeconds);
Ok so recently I made a project which had like a bit of a gravity timer,
int speed = 5;
NSTimer *gravitytimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(gravity) userInfo:nil repeats:YES];
-(void)gravity {
image.center = CGPointMake(image.center.x, image.center.y - speed)
}
The problem is that the speed keeps multiplying or keeps adding and the image goes faster and faster. I don't know what the problem is. I am a newbie so sorry if this is a bad question. Thanks to all the people who take the time to answer.
When you create a timer, while it will try to call it every 0.01 seconds, you actually have no assurances that it will be called precisely at that rate (i.e. if it takes too long, it may skip one or two; if the main thread is blocked doing something else (and it's quite busy when the app first starts), you may skip quite a few). You can request to update image.center 100 times per second, but you have no guarantee that this is how often it actually will end up getting called.
If you wanted to use this technique to animate, you do so in a manner that isolates the speed of the animation from the frequency of the timer's selector is actually called. So, you might capture the start time, e.g.
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
CGPoint startPoint = image.center;
And then in your timer routine, you'd capture the elapsed time, multiply your speed times the elapsed time, and go from there:
-(void)gravity {
CFAbsoluteTime elapsed = CFAbsoluteTimeGetCurrent() - self.start;
CGFloat speed = 100.0; // e.g. 100 points per second
CGPoint center = startPoint;
center.y += (elapsed * speed);
image.center = center;
}
As an aside, I assume this is just an exercise in timers. If this were a real animation, there are far more effective ways to do such animation (e.g. block-based animateWithDuration, UIKit Dynamics, and if you really wanted to do something timer-based, you'd often use CADisplayLink rather than a NSTimer). Also, BTW, the frame rate of the display is 60fps, so there's no point in trying to call it more frequently than that.
I want my app to be able to count the number of taps every second. I assume this would have something to do with touchesBegan:..., but that doesn't work on a button, does it? Anyway, how would I measure the number of taps per second?
I think I could do it manually using a counter which resets every second but I was wondering if there is a better way.
Would it add the values to an array? And if so, would I be able to calculate an average excluding 0's?
My current code.
-(void) timer:(NSTimer *)averageTimer {
if(tapCountInLastSecond != 0) {
secondsElapsed++;
averageTapsPerSecond += tapCountInLastSecond / secondsElapsed;
tapCountInLastSecond = 0;
NSLog(#"Average: %f", averageTapsPerSecond);
}
}
in your viewController put those counters
int tapCountInPastSecond = 0;
float averageTapsPerSecond = 0;
int secondsElapsed = 0;
Then add this method that invokes when you the screen or tap a button
- (void)incrementTapCount
{
tapCountInPastSecond++;
}
Create a timer that will fire every second, doing it's calculations, then resets the tap count
- (void)timerActions
{
secondsElapsed++;
averageTapsPerSecond = (averageTapsPerSecond*(secondsElapsed-1) +tapCountInPastSecond) / secondsElapsed;
tapCountInpastSecond = 0;
}
Now you can init your timer like that:
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(timerActions) userInfo:Nil repeats:YES];
Then at any point you'll be able to get the average Taps/Second by reading the value averageTapsPerSecond
Hope this make sense to you
I have an animation of a drinking glass filling up from empty to full, using CAKeyframeAnimation. The animation works perfectly fine.
I need to update a UILabel with the percentage corresponding to the fullness of the glass, i.e. it will read "0%" when the animation begins, and "100%" when it ends.
The keyframe animation runs for 5 seconds. I don't see a good way of updating this label. I can think of two options:
starting another thread and running a polling-type loop that updates the text at the cost of processing power.
break down the animation into 100 parts and use CABasicAnimation to update the text and then proceed with the next bit of glass animation.
Is there a better way to do this?
Thanks in advance
You can use either a NSTImer or dispatch_after() blocks to update the label at some scheduled interval:
// assume an ivar "NSTimer *myTimer" and "int count", initially 0
// fires 20 times, so update is 0.05
myTimer = NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:#selector(updateLabel:) userInfo:nil repeats:YES
- (void)updateLabel:(NSTimer *)timer
{
++count;
if(count >= 20) {
[timer invalidate];
}
CGFloat percent += 0.05;
myLabel.text = [NSString stringWithFormat:...
}