Back button seems disabled iOS - iphone

In iOs I navigate (pushed) with a navigation controller, and in the viewDidLoad launch a request. This request take might take a long time, and I'd like the users will be able to go back if they won't want wait for the request.
The problem it's that the back button added in the navigation bar seems to be blocked until de request finishes. The button remember the user interaction and when the request finishes go back automatically.
The request has a delegate method for the response and when the app enters on that method the button wake up and go back.
If I touch during a request the touch/click effect don't appear on the button, and it don't either at the end of the request. When I wait until the end, the button had the normal effect for a touched/clicked button.

For that you can enable the button property like this.
[button setEnable:Yes];
[button setEnable:Yes];
also use this
[button setuserintractionEnable:no];

call your request in backgroundthread as
[self performSelectorInBackground:#selector(startRequest) withObject:nil];
and remember this always for core data too. this is that your UI will be rleased and the request will continue to work in background thread
and then implement request cancel on back button
initialize obj as
Obj *obj = [[Obj alloc] initWithDelegate:self selector:#selector(requestFinished)];
[self performSelectorInBackground:#selector(startRequest:) withObject:obj];
obj has the attributes SEL selector, and id delegate;
when request finishes
check
if ([obj.delegate respondsToSelector:obj.selctor])
{
[obj.delegat performSelector:obj.selector];
}
inform me if you need more specs

Related

Activity Indicator not showing up

I have two issues with activity indicator:
1. Activity Indicator not showing up on UIViewController
I have activity indicator added in .xib file. On button click it should start animating. and when response from server is received, before going to next page it should stop animating.
I am doing it as follows:
activityIndicator.hidden = NO;
[activityIndicator performSelector:#selector(startAnimating) withObject:nil afterDelay:0.1];
[self.view bringSubviewToFront:activityIndicator];
....rest of code here....
activityIndicator.hidden = YES;
[activityIndicator stopAnimating];
Activity Indicator not showing up on UITableView
For table view I am doing it same way but on didselectrowatindexpath...
For tableview I also tried adding activity view to cell accessory, but still not showing up
In both cases activity Indicator is not showing up.
Please help
Thanks
If all this code is in one method or in response to one event, then none of the changes to the views are going be visible until you return to the event loop. You set the activityIndicator.hidden to NO and then set it again to YES before the UI has an opportunity to even refresh.
You also apparently stop the animation before you start it.
What you need to do is make the activity indicator visible here and start its animation. Then schedule the work to be done (start an asynchronous network connection, or put some work into a queue, or whatever it is you need to get done) and return from this method so that the UI can refresh, the indicator can be drawn, and the animation can actually start.
Then later at some point after the work is complete, you can hide the indicator and stop the animation. But you can't do all of that on the main thread within one single turn of the event loop. None of your changes will be visible because no drawing at all will happen here while this method is executing (assuming this is on the main thread)
I hope that makes sense?
Now I modified the code to this:
activityIndicator.hidden = NO;
[activityIndicator startAnimating];
[self performSelector:#selector(saveClicked) withObject:nil afterDelay:0.1];
[self.view bringSubviewToFront:activityIndicator];
and it worked :)
May be, in tableView, instead of self.view , it will be self.navigationController.view ??

Temporarily Stop UIButton from responding

I have a button in my app that calls a long asynchronous function that we do not want to have called multiple times concurrently. However when I start mashing the button, it always sends as many messages as taps. I want to stop the button from responding while the function is running. I currently have a flag that stops execution of the function when the function is active in another thread, and the button is set to be hidden as soon as it enters this function, but these don't have any effect.
Thanks for any help!
Assuming:
Your button has an IBOutlet reference.
You have an IBAction on the button.
Then you can simply set the button's Enabled property to NO, and re-enabled when you receive notification from your ASYNC task that its done.
-(IBAction) buttonClicked {
[myButton setEnabled:NO];
//Do stuff
}
-(void) notificationHandlerMethodForAsyncTaskDone:(NSNotification *)notification {
[myButton setEnabled:YES];
//Do stuff
}
Inside the method that handle the touch event you can put disable the button:
- (void)handleTouch:(id)sender {
// Do your asynchronous call
[sender setEnabled:NO];
}
Instead of thinking about disabling the button why not make the screen inactive. Show some message like "Processing..." or a Spinner. That way the user will know the something is happening & at the same time your problem is solved.
DSActivityView is a good library for this.
You can use the enabled property to turn the button off:
[myButton setEnabled:NO]
Documentation

Stopping updation of CALayer's contents in iPhone

I am working on a pdf Reader application.I am making use of CALayer to render the pdf contents.i employed swipe gesture to navigate across the pages.The issue is, if the user attempts to go to next or previous page once the rendering of layer has started,the 'going to next page' action is being performed after completion of rendering of the current pdf page on to the layer.I want the rendering of the current page to be stopped immediately as soon as the swipe occurred and next page should start rendering on the layer.any idea please help.
UPDate:
here is my code
-(void)loadSinglePageWithWidth:(float)width andHeight:(float)height{
draw=0;
NSLog(#"before draw");
[markupView.layer insertSublayer:renderingLayer1 above:tiledLayer1];
loadingThread=[[NSThread alloc] initWithTarget:self selector:#selector(loadSinglePage) object:nil];
[loadingThread start];
}
-(void)loadSinglePage{
[renderingLayer1 setNeedsDisplay];
}
as soon as i swipe, in my action method, the code is written like
[loadingThread cancel];
[loadingThread release];
loadingThread=nil;
even i cancel the "loadingThread" the execution of the drawLayer: method seems to be running.am i correct with this thread approach?will drawLayer: code be executed by the thread which i am using to call setNeedsDisplay method?
I think that the best solution is to do the rendering in a separate thread. Once it's done, you simply display the rendered image on the screen. If not, you can always cancel the operation.

How to solve UIThread bloack issue in iPhone

I am creating an iPhone application where I need to show a login screen for few minutes, hence I created the custom view and added to the custom view controller which is added to the window for display. Now at the same time I need to check for some background database so, I am creating that in separate delegate and while after database operation is in finished it gives an callback to the main thread to display the new screen. But the first view is never getting displayed and my application directly lands up in the new view.
Please find below my code snippet:
(void)CheckForExistingData : (DatabaseSource *)theDatabaseConnection
{
BOOL isRecordExist = theDatabaseConnection.isrecordExist;
// Release the connection....
[theDatabaseConnection release];
theDatabaseConnection = nil;
if (isRecordExist == FALSE)
{
textLabel.text = #"Preparing the application for first time use, please wait....";
[activityIndicator startAnimating];
[self setNeedsDisplay];
}
else
{
// Now all categories are successfully downloaded, launch the category screen...
sleep(2); // sleep for 1 second to allow to show the splash screen....
[self.viewController LaunchCategoryViewController:self];
}
}
Here CheckForExistingData is an callback mechanism which will be called from the other thread.
You need to exit your method to see anything displayed. Not sleep or wait on a synchronous network call.
That probably means you need to break your sequential code into multiple methods, the subsequent parts being called by a splash wait timer, the view button handler, or the async network activity completion callback.
sleep() blocks your main thread, thus the UI has no chance to update.
But you can always send messages delayed. In your case, it would look like this:
[self.viewController performSelector:#selector(LaunchCategoryViewController:) withObject:self afterDelay:2.0];

How to tell iPhone OS function to stop/cancel?

I have an action which begins when the user taps a button on the screen (e.g. "Import"). At the same time, a UIToolbar appears on the bottom of the screen which gives the user the option to cancel this action. How can I properly send a cancel message to the initial function? If the user hits "Cancel," I do not want the "Import" to continue. In theory I could set it up as a separate thread (which I could then kill), but I am not sure what is the proper way to do this so that it could clean up after itself. What are some other strategies to be able to "kill" a function which the user has already begun?
Create a separate operation using something like:
NSOperationQueue* queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation: [[[NSInvocationOperation alloc] initWithTarget: self
selector: #selector(_backgroundWorker)
object: nil] autorelease]];
This way _backgroundWorker will be executed without stopping main UI thread.
One Cancel button is pressed, set some internal variable and check its value inside _backgroundWorker.