Refresh iPhone For progressbar - iphone

How would i show that the progress bar is working there is no Refresh() in objective-c like there is in .net what would i use
for example
contactprogress.progress = 0.5;
StatusLabel.text = #"Status: Address Found";
How would i refresh the view to show that the progress has changed & show user the StatusLabel status?
Thanks
Mason

Based on your comments to the other two responses, you're doing some computationally intensive task that takes a few seconds, and the view is not updating during the task. You could try using two threads (not as scary as it sounds) so that the UI can continue updating while the task is doing its thing.
Here is an example.
iOS Reference Library Threading Programming Guide

It sounds like you want to update a progress bar and some text repeatedly with some time interval between. You could use a simple timer. Read about timers here. Perhaps something like this:
[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:#selector(refreshProgress) userInfo:nil repeats:YES];
and:
- (void) refreshProgress:(id)sender {
// figure out new progress bar and text values
contactprogress.progress = 0.5;
StatusLabel.text = #"Status: Address Found";
// check if we should stop the timer and hide the progress bar/status text
}
That would update your progress bar with new values every 0.1 seconds.

To redraw an UIView, you can use
[UIView setNeedsDisplay];
However, you will need this only in very rare cases. When you change, let's say the contents of a label, your UI should update instantly. You might want to provide more code/context for your problem.

Related

multitasking in ios 4 later for notifications

i want to run one of my services in the background even my app is in foreground or background states,if i get any data from that service i want to show that one as a notification to the user. how can i proceed .
as my reserach gives me an idea to follow multi taking in iphone .
or shall i use any timer so that the method calls for particular time interval for every time
NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:#selector(notification) userInfo:nil repeats:YES];
[timer fire];
-(void)notification
{
//shall i write all of my services here
}
or shall i create any new threads like
[self performSelectorInBackground:#selector(notification) withObject:Nil];
in AppDelegate file .
or shall i need to follow any other thing plz guide me thank you.
Generally, you should consider using push notifications sent by the server to show notifications to the user when something changes. This is preferable to running in the background since it is better for system performance & battery life.

Updating UI concurrently on iOS

I have two scroll views in my app, one containing UIImageViews, one containing UIButtons. Using NSTimer, I'm making them scroll automatically. However, if one of the scroll views is tampered with (a finger touches it and starts scrolling manually), the other scroll view stops as well. Is there any way to stop this from happening? Or is it normal?
Also, the UIButtons inside the second scroll view are tap-able, but they don't show the standard highlighting. If I enable the glow effect, it works, but not the standard highlighting. Is there anyway I can make this work as well?
My code for NSTimer is
[NSTimer scheduledTimerWithTimeInterval:0.018
target:self
selector:#selector(onTimerScrollText)
userInfo:nil
repeats:YES];
- (void)onTimerScrollText {
CGFloat x = self.textScroller.contentOffset.x;
x += 0.5;
[self.textScroller setContentOffset:CGPointMake(x, 0)];
}
And it's pretty much the same for the image scroller.
Thanks!
The initial problem of one scrollview no longer scrolling until the other manual scroll has finished has been solved.
The solution is simple. Each timer needs to be added to the run loop:
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
Now they both work regardless of whether one is interrupted by one's finger.

UIProgressView not showing on iPhone but shows in simulator

I have a UIProgressView called progTimer that I placed on my View Controller via Interface Builder. On the iOS simulator, the UIProgressView shows up just fine, but when I test it on my iPhone it doesn't appear.
Here is the code that modifies it.
- (IBAction)scanbtn
{
[progTimer invalidate];//cancels timer if currently running
progTimer=nil;
progNum = 0;
progTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 //timer to update the progress view
target:self
selector:#selector(progIncrease)
userInfo:nil
repeats:YES];
[self scan];
}
-(void) progIncrease
{
progNum = progNum + 0.01;
scanProg.progress = progNum;
if (progNum >=1)
{
[progTimer invalidate];
progTimer=nil;
//[alert show];
}
}
Any ideas? Thanks in advance. .
ALL: For some reason, I changed the style of the Progress View to "Bar" and it shows up fine. No idea what caused the initial problem, but now it works albeit having a different style bar.
My guess would be that on the device, the scanning process is moving so fast that you just can't see it. To make sure it's working ad and NSLog in the ProgressIncrease method to see how fast it scans. I had the same problem with my preloading notifiers, that were showing on the simulator but not on the device.
You call [self scan]; which seems to be the culprit. How long does that scan operation run?
Its very important to note that while any long running operation runs in main thread which is UI thread, no other code in the main thread loop will be executed(until that long running operation finishes) which means your timer function or even pressing button after pressed once pressed won't work. You need to use either NSOperation and dispatch queue or create a thread and run the scan operation in the background and send notifications to main thread using NSMachPort or NSObject performSelectr:OnThread:... etc for it to update the progress bar.
By the way, the scanning process and the progress bar has no relation at all; The progress bar should ideally update how much of scanning is done which means the scanning process must inform progress bar to update that also in main thread if scanning is running in secondary thread.

iPhone: Loading data with a progress animation?

I'm creating an iPhone app and am wondering how to have a progress animation when you're loading data? I see this a lot in applications such as Tweetie, but haven't been able to figure it out myself.
If you are talking about loading data over a network, ASIHTTPRequest provides a way to pass a reference to a UIProgressView that it will update with accurate progress for both downloads and uploads. I highly recommend it.
If you only want the small network spinner in the statusbar you activate it with
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
...and deactivate
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
In an app I wrote for our company that performs a very long sync (by accessing a web service), I display an UIActivityIndicatorView.
On the same view, I also included a label that displays "Fetching X of Y..." The label is updated via an NSTimer. The call looks like:
timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(updateLabel:) userInfo:nil repeats:YES];
In addition, in order for the UI to actually update, I had to spin off the code to fetch data from the webservice into its own thread.
Do you mean a progress bar, or an activity indicator? For an occurring activity, you can use UIActivityIndicatorView.
The flow will look a little like this.
UIActivityIndivatorView *activity = [[UIActivityIndivatorView alloc] init];
//attach activity to a view or a bar
//begin activity
[activity startAnimating];
//here will be the functionality for your data gathering progress
//once your progress or activity is done
[activity stopAnimating];
Hope this helps.

Keeping a UISegmentedControl (among others) responsive

I have a segmented control being used as a toggle. When toggled, I switch a bunch of contents around in a table view which takes a tiny but noticeable amount of time (inserting/deleting sections in the table view, animating the change, etc). I want the segmented control to respond to the selection immediately. So in my action handling code for the segmented control's UIControlEventValueChanged event, I do the following:
- (IBAction)groupingChanged:(id)sender {
UISegmentedControl *seg = sender;
[tableModel toggleOn:[seg selectedSegmentIndex] == ToggleOnIndex];
[self performSelectorOnMainThread:#selector(updateGrouping)
withObject:nil
waitUntilDone:NO];
}
Where updateGrouping is:
- (void)updateGrouping {
MXAssertMainThread();
[tableView beginUpdates];
... several table updates
[tableView endUpdates];
}
Setting waitUntilDone:NO allows the groupingChanged method to complete before the updateGrouping is called, but this doesn't seem to be sufficient to repaint the view. The segmented control sticks until the table is done updating, then it switches over.
So I tried modifying groupingChanged: to create a thread for the update like so:
- (void)delayed {
[self performSelectorOnMainThread:#selector(updateGrouping)
withObject:nil
waitUntilDone:NO];
}
- (IBAction)groupingChanged:(id)sender {
UISegmentedControl *seg = sender;
[tableModel toggleOn:[seg selectedSegmentIndex] == ToggleOnIndex];
[self performSelectorInBackground:#selector(delayed) withObject:nil];
}
And this does work. The segmented control toggles instantly and the table soon follows. But I'm not at all confident of the result. Is it simply a side-effect of giving the main thread a reprieve while the new thread started up? Is this just how I need to queue updates to the UI? It's clearly hacky. I'm hoping someone has a better pattern they're following for this situation.
Think of it this way - everything you do is generally done on the main thread, including UI updates.
So in your original code, the code that updated the table view was reached before the code that did the UI update on the segment.
So, you were correct that giving the main thread a break allowed more time to complete the updates to the UI, because the main thread was allowed to complete the UI updates while the background thread handled the table updates.
An alternative you could try is to use performSelector:withObject:afterDelay with a 0.0 delay (which allows the main thread to process other things before proceeding with the selector). It may work where performSelectorOnMainThread did not, as that call may be more immediate even though they end up doing something very similar.
If you just want to make sure the segmented control gets repainted real quick, I probably wouldn't dive into threads.
Instead I would just set a timer with a low value like 0.1, and that should be sufficient enough to get the control updated without any noticeable delay to the user.
I've used this when I have a lot of work to do but need a quick UI update.
Still a little "hacky", but without the introduction of threads.
So...
- (IBAction)groupingChanged:(id)sender {
UISegmentedControl *seg = sender;
[tableModel toggleOn:[seg selectedSegmentIndex] == ToggleOnIndex];
[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:#selector(updateGrouping)
userInfo:nil
repeats:NO];
}
I hit the same problem and solved it by subclassing the UISegmentedControl to create a Delayed UISegmentedControl.
In the delayed control I overrode addTarget:action:forControlEvents: to capture the target & action. Then when the segment event occurs I run an NSTimer to launch the captured target & action after a set delay. The result is that the UI gets updated to display the segment clicked and I can use the DelayedUISegmentedControl like I would a UISegmentedControl:
// Follows all normal initialization patterns of UISegmentedControl
UISegmentedControl *segmentedControl = [[DelayedUISegmentedControl alloc]
initWithItems:[NSArray arrayWithObjects: #"First", #"Second", nil]];
// Adds a delay to the selector; default is 0.25
[segmentedControl addTarget:self action:#selector(segmentAction:)
forControlEvents:UIControlEventValueChanged];
If you want to download the control I've open sourced it on google code.