I am working on pdf reader app.i am using gestures for rendering next page from the current page,for this i am using swipe.
1.My work is working well.
2. For each time i am calling drawLayer using setNeedsDisplay.
3.My app is working fine if the swipe is slow means while page rendering is in process if i swipe then it is getting crashing.
can any one help me to solve this issue with some library files.
Thank you all,
this is the answer for the above question [NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(loadPagesAccordingToCurrentOrientation) object:nil]; [self performSelector:#selector(loadPagesAccordingToCurrentOrientation) withObject:nil afterDelay:0.5];
Related
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.
I have a UITableView with a list of items, each having it's own image. I thought Apple's LazyTableImages sample project would be perfect to learn from, and use to implement the same kind of process of downloading images asynchronously, after the original list data is retrieved.
For the most part, it works quite well, except I did notice a subtle difference in behavior, between this sample app, and how the actual app store downloads images.
If you launch the LazyTableImages sample, then do a quick flick-scroll down, you'll see that the images do not get displayed until after the scrolling comes to a complete stop.
Now, if you do the same test with a list of items in the actual app store, you'll see that the images start displaying as soon as the new items come into view, even if scrolling hasn't stopped yet.
I'm trying to achieve these same results, but so far I'm not making any progress. Does anyone have any ideas on how to do this?
Thanks!
I'm baffled that nobody could answer this...
So, I eventually figured out how to acheive the exact same effect that is used in the actual app store, in regards to how the icons are downloaded/displayed.
Take the LazyTableImages sample project and make a few simpled modifications.
Go into the root view controller and remove all checks regarding is table scrolling and/or decelerating in cellForRowAtIndexPath
Remove all calls to loadImagesForOnScreenRows, and thus remove that method as well.
Go into IconDownload.m and change the startDownload method to not do an async image downlaod, but instead do a sync download on a background thread. Remove all the code in startDownload, and add the following, so it looks like this:
- (void)startDownload
{
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(loadImage) object:nil];
[queue addOperation:operation];
[operation release];
[queue release];
}
Then, add a loadImage, like this:
- (void)loadImage
{
NSData *imageData = [[NSData alloc] initWithContents OfURL:[NSURL URLWithString:appRecord.imageURLString]];
self.apprecord.appIcon = [UIImage imageWithData:imageData];
[imageData release];
[self performSelectorOnMainThread:#selector(notifyMainThread) withObject:nil waitUntilDone:NO];
}
Then, add notifyMainThread like this:
- (void)notifyMainThread
{
[delegate appImageDidLoad:self.indexPathInTableView];
}
Done! Run it, and you will see the exact app store behavior, no more waiting to request image downloads until scrolling stops, and no more waiting for images to display until scrolling stops, or until user has removed their finger from the screen.
Images are downloaded as soon as the cell is ready to be displayed, and the image is displayed as soon as it is downloaded, period.
Sorry for any typos, I didn't paste this from my app, I typed it in, since I'm away from my mac right now...
Anyway, I hope this helps you all...
Check out UIScrollViewDelegate. I've implemented something like this by listening for scrollViewDidScroll:, calculating the scroll speed (by checking the contentOffset against the last recorded contentOffset, divided by the difference in time), and starting to load images once the speed drops below a certain threshold. (You could achieve something similar with UIScrollViewDelegate's scrollViewDidEndDragging:willDecelerate: as well).
Of course, you don't have to check the speed; you could just load images on UITableViewDelegate's tableView:willDisplayCell:forRowAtIndexPath: whenever you see a new cell, but I've found that if the user is flipping through tons of cells, you don't need to bother until you see that they're going to slow down to browse.
I am developing an pdf reader in which i have to load each page of the pdf book on finger swipe. For each swipe i am incrementing one page it is working fine if i am swiping slowly.where it is not at all working if the swipe is so fast it gets crashed.
hi folks i resolved the above issue with the NSobject class reference it has only two lines..
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(loadPagesAccordingToCurrentOrientation) object:nil];
[self performSelector:#selector(loadPagesAccordingToCurrentOrientation) withObject:nil afterDelay:0.5];
I cant be sure but It feels like you are not accounting for the use case where one page may not have finished rendering while another comes into the pipe.
The line in
loadSinglePageWithWidth:(float)width andHeight:(float)height
myPageRef = CGPDFDocumentGetPage(...
feels especially unstable even if wrapped in the #synchronised pragma.
I think you need to account for that situation and cancel any existing renderings/animations before allowing the next one to begin.
SO isnt a debugger.
some of the code is used for my problem
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(loadPagesAccordingToCurrentOrientation) object:nil];
[self performSelector:#selector(loadPagesAccordingToCurrentOrientation) withObject:nil afterDelay:0.5];
I'm trying to transition between loading of different web pages by hiding the webView while it is loading a page. However, I'm seeing that some image intensive websites are causing webViewDidFinishLoading to fire too soon and when I show the webView at that point then for a split second you get a view of the previous page. Any ideas on how to resolve this?
If there's Javascript on the page, you may need to wait for it to finish. The easiest way seems to be to send some javascript to the page to be executed:
-(void) webViewDidFinishLoad:(UIWebView *)webView
{
NSString *javaScript = #"<script type=\"text/javascript\">function myFunction(){return 1+1;}</script>";
[webView stringByEvaluatingJavaScriptFromString:javaScript];
// done here
}
Having said that, I seem to still see cases where the webview isn't quite updated within webViewDidFinishLoad.
I've encountered this problem as well. Although I haven't found a solution, I've worked around the problem by introducing a 0.5 second delay before showing the UIWebView once the webViewDidFinishLoading delegate method is called.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[self performSelector:#selector(displayWebView) withObject:nil afterDelay:0.5];
}
I'm working on an app right now that was working fine until I started implementing some threading for background loading of images. Now theres no crashes but the keyboard does not display. That is to say its invisible (I can still type, I just cant see the actual keyboard).
The only thing I've done was implement threading so I'm wondering if I'm somehow messing with the thread the keyboard runs on or something?
The threads I'm calling are like:
[NSThread detachNewThreadSelector:#selector(loadWebView:)
toTarget:self withObject:[NSNumber numberWithInt:pageNum]];
and
[scrollView performSelectorOnMainThread:#selector(addSubview:)
withObject:curWebView waitUntilDone:NO];
Thanks in advance.
UIWebViews (and all UI elements) cannot be used on background threads safely. If you wish to load images in the background, use NSURLConnection's asynchronous loading methods.