Is there any method for slide show of an array of strings in UILabel in iphone app?(ie, strings will appear one by one). Anyone please help me.
Look at NSTimer.
This can get you a repeated callback every X seconds. You can use this to swap the strings in an array.
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(swapStrings:) userInfo:nil repeats:YES];
_myStrings = #[ #"a" , #"b", ..... ];
...
- (void) swapStirings:(id)sender
{
myInt ++;
if (myInt >= [_myStrings count]) myInt = 0;
myLabel.text = [_myStrings objectAtIndex:myInt];
}
No, there is not. But, the good news it should be trivial to implement. I suggest creating a subclass of uilabel that has an array of strings as an ivar. The subclass has an init method that sets the array and a time interval. Then it uses an nstimer to change its label and redisplay itself. Good luck!
Related
I want to set the value of my uislider like this (4.8,4.9,4.10,4.11,5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,5.10,5.11,6.0,6.1,6.2,6.3) but don't know how to do that. Can anyone help me with this? I even don't know how to code this. I only created the outlet of uislider.
you can set slidervalue like,
self.mySlider.minimumValue = 4.8;
selfmySlider.maximumValue = 6.8;
self.mySlider.value = 5.8; //cuerrent value
if you change above value (as per question) then you can shedule timer (NSTimer) and in selector method of this timer you can change slidervalue according to your value array that posted in question.
Update as per comment :
NSTimer * sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateSlider) userInfo:nil repeats:YES];
int counter = 0; take counter to differentiate object.
NSArray *arr = []; //this is your value arr according to question
then in your update slider method update your slider smething like,
- (void)updateSlider{
mySlider.value = [[arr objectAtIndex:counter] floatValue];
counter ++;
}
Something lie this, manage according to your context. this is example. and please avoid syntax mistake if any.
Hope this will help :)
I want to use a speech synthesised sentence in an application demo. After pressing a button, a timer runs and after for example 12 seconds the first sentence is being spoken, then after 1.30min and so on.
The approach I was thinking of, is an NS Timer. But as far as I can see it only plays after a defined time. So do I need for any timespan a new timer? or can I track the time left and invoke a method call when a specific time is reached?
Thanks
I would do this using a dictionary with NSNumbers as the keys (representing seconds), and the sentence you want spoken as the value. Use a simple timer firing once every second, that updates an int, which (when converted to an NSNumber) would be checked against the dictionaries keys. I'm just logging in this example, but this should get you started,
- (void)viewDidLoad {
[super viewDidLoad];
self.dict = #{#3:#"First", #5:#"second", #11:#"Third", #35:#"Fourth"};
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(doStuff:) userInfo:nil repeats:YES];
}
-(void)doStuff:(NSTimer *) aTimer {
static int i = 0;
i++;
if ([self.dict.allKeys containsObject:#(i)]) {
NSLog(#"%#", self.dict[#(i)]);
}
}
I have surfed on a bunch of resources from the internet but still couldn't get any idea of what I'm trying to implement.
I would like to record user preferences by detecting how much time they have stayed in each information pages.
In order to make this question simpler, that says I have a entrance page with 5 different theme pages which represent different information.
I would like to know which page is the page that user most interesting.
What I wish to do is to put a counter in each theme pages and calculate how much time they stay in that page (the counter should be able to pause for reentrance), and then when I press a button on the entrance page, an alert will tell me which page is the page that user spent most of time on it.
I hope this make sense!
Does anyone have any experience on this? I would be most appreciative if anyone can provide some codes and examples for me.
ViewController A:
- (void)viewDidLoad {
[super viewDidLoad];
//create iVar of NSInteger *seconds
seconds = 0;
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:#selector(increaseTimeCount) userInfo:nil repeats:YES];
[timer fire];
}
- (void)increaseTimeCount {
seconds++;
}
- (void)dealloc {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// you can add to array too , if you want and get average of all values later
[defaults setInteger:seconds forKey: NSStringFromClass(self)];
}
now in Entrance View ..
get the time as
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger *secondsInView = [defaults integerForKey:NSStringFromClass(View1ClassName)];
Firstly I'd like to draw your attention to the Cocoa/CF documentation (which is always a great first port of call). The Apple docs have a section at the top of each reference article called "Companion Guides", which lists guides for the topic being documented (if any exist). For example, with NSTimer, the documentation lists two companion guides:
Timer Programming Topics for Cocoa
Threading Programming Guide
For your situation, the Timer Programming Topics article is likely to be the most useful, whilst threading topics are related but not the most directly related to the class being documented. If you take a look at the Timer Programming Topics article, it's divided into two parts:
Timers
Using Timers
For articles that take this format, there is often an overview of the class and what it's used for, and then some sample code on how to use it, in this case in the "Using Timers" section. There are sections on "Creating and Scheduling a Timer", "Stopping a Timer" and "Memory Management".There are a couple of ways of using a timer. From the article, creating a scheduled, non-repeating timer can be done something like this:
1) scheduled timer & using selector
NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:#selector(onTick:)
userInfo: nil repeats:NO];
if you set repeats to NO, the timer will wait 2 seconds before
running the selector and after that it will stop;
if repeat: YES, the timer will start immediatelly and will repeat
calling the selector every 2 seconds;
to stop the timer you call the timer's -invalidate method: [t
invalidate]; As a side note, instead of using a timer that doesn't
repeat and calls the selector after a specified interval, you could
use a simple statement like this:
[self performSelector:#selector(onTick:) withObject:nil afterDelay:2.0];
this will have the same effect as the sample code above; but if you want to call the selector every nth time, you use the timer with repeats:YES;
2) self-scheduled timer
NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
NSTimer *t = [[NSTimer alloc] initWithFireDate: d
interval: 1
target: self
selector:#selector(onTick:)
userInfo:nil repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:t forMode: NSDefaultRunLoopMode];
[t release];
this will create a timer that will start itself on a custom date
specified by you (in this case, after a minute), and repeats itself
every one second
3) unscheduled timer & using invocation
NSMethodSignature *sgn = [self methodSignatureForSelector:#selector(onTick:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:#selector(onTick:)];
NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
invocation:inv
repeats:YES];
and after that, you start the timer manually whenever you need like this:
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];
And as a note, onTick: method looks like this:
-(void)onTick:(NSTimer *)timer {
//do smth
}
Try this simple method:
- (void)viewDidLoad
{
[super viewDidLoad];
count = 0; // Declare int * count as global variable;
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(timerAction) userInfo:nil repeats:YES];
}
- (void)timerAction
{
[self custom_method:count++]
}
Might I suggest a different route. If you take the time since reference date, when the user enters the page:
NSTimeINterval time = [NSDate timeIntervalSinceReferenceDate]
then do the same when they leave the page and compare them.
timeOnPage = time - time2;
This is much more efficient than firing a timer on another thread unnecessary.
You do not need to use NSTimers for this at all.
Store the date/time when the user starts viewing, and calculate the time difference when they stop viewing using simple time arithmetic.
Exactly As Dave Wood says You should use date and time for starting and ending viewing that screen and calculate the difference and then save it to any integer variable.Using NSTimer will make the performance effect in your app and make the compiler busy while incrementing the count.
I'm working on a project, where i have to update the text of a UILabel really regularly (0.085f). So, I insert the update of the label in a loop like this :
MetresNumber = MetresNumber + 0.25;
DisplayMetres.text = [NSString stringWithFormat:#"%07.0f", MetresNumber];
I precise that "MetresNumber" is a float, and "DisplayMetres" the UILabel.
And this sort of code really really makes bad performances ! It's incredible how slower it goes since i've added those lines.
I made some searches, and found elements like :
[DisplayMetres setNeedsDisplay];
But it didn't change and update the text on the label.
It's in a loop called with :
timer = [NSTimer scheduledTimerWithTimeInterval:0.085 target:self selector:#selector(myLoop) userInfo:nil repeats:YES];
So my question is, could my code be improve, to get better performances, or should i forget my UILabel because it's too slow with ?
Thanks !
(void)setNeedsLayout
Call this method on your application’s main thread when you want to adjust the layout of a view’s subviews. This method makes a note of the request and returns immediately. Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate all of your layout updates to one update cycle, which is usually better for performance.
Another problem is that a scheduledTimer will not get called while the main thread is tracking touches. You need to schedule the timer in the main run loop.
So instead of doing
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateLabel:) userInfo:nil repeats:YES];
use
NSTimer* timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:#selector(updateLabel:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
Also Use Timer selector method like below:
- (void) updateLabel:(id) sender {
MetresNumber = MetresNumber + 0.25;
NSString *text = [NSString stringWithFormat:#"%07.0f", MetresNumber];
dispatch_sync(dispatch_get_main_queue(), ^{
DisplayMetres.text = text;
});
}
There shouldn't be any performance issues when you are just updating a single label every 85ms. First find out what actually causes the lags. Use the Time Profiler instrument.
I think most time will be spent on the string drawing.
Here are some tips how you can optimize your code:
You don't need to call setNeedsLayout or setNeedsDisplay explicitely on the label. Just set the text property (on the main thread of course).
The resulting string in your code will always be a 7-digit integer. Consider using an integer instead of a float. Formatting an integer will be faster.
stringWithFormat can be slow sometimes. You could try using a NSNumberFormatter or simply generate the string with: [#(MetresNumber) stringValue]
In your code the string actually doesn't change everytime the timer fires. Only every 4th time. You can set the time interval to 4*0.085 and replace MetresNumber = MetresNumber + 0.25 with MetresNumber = MetresNumber + 1.
Try using this custom UILabel class
Don't use UILabel at all. Use pre-drawn images for each digit.
Schedule the timer with NSRunLoopCommonModes (see answer from Lightygalaxy)
I want a timer to stop at a user-defined input from a text field, then reset and repeat until it reaches a user-defined number of repetitions (another text field). This worked well when I was using sliders, but I was having some other problems with sliders so I changed to textfields. I think the problem is converting the text field into a numeric value, which I have tried many different ways without success. The app is a simple exercise repetition counter with a hold time. Any assistance is greatly appreciated. Thank you...
-(void)countup {
float floatHoldTime=[holdTimeText.text floatValue];
float floatReps=[repsText.text floatValue];
CountHold ++;
displayHoldTime.text = [NSString stringWithFormat:#"%i", CountHold];
if (CountHold == floatHoldTime) {
CountRep ++;
displayReps.text = [NSString stringWithFormat:#"%i", CountRep];
CountHold = 0;
}
if (CountRep == floatReps) {
[Timer invalidate];
Timer = nil;
}
}
-(IBAction)start:(id)sender {
Timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(countup) userInfo:nil repeats:YES];
}
I suspect that the problem is that your float and what I presume is an int (CountHold) are never quite equal due to the way that floats are represented inside a computer. Either make floatHoldTime and floatReps integers, or make you comparison something like CountHold - floatHoldTime < 0.01 to allow for a little slop.