CatNiP prefinal
Sähköinen nuottikirja, HY-TKTKL-OHTUPROJ KESÄ11
/Users/awniemel/Notepad-SVN/svn/trunk/CatNiP/CatNiP/UIDocumentView.m
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #import "UIDocumentView.h"
00021 
00022 @implementation UIDocumentView
00023 
00024 @synthesize preloadFactor;
00025 @synthesize placeholder;
00026 @synthesize delegate;
00027 
00035 - (void)setDocument:(UIDocument *)value
00036 {
00037     // Safely set the new value and release the old one
00038     [value retain];
00039     [document release];
00040     document = value;
00041     
00042     // Remove all old UIImageViews
00043     for(UIView *view in container.subviews)
00044         [view removeFromSuperview];
00045     
00046     // Create new UIImageViews for the pages
00047     CGPoint pageOrigin = CGPointZero;
00048     for(int i = 1; i <= document.numberOfPages; ++i)
00049     {
00050         // Calculate the frame of the current page: horizontally centered and
00051         // vertically directly below the last one
00052         CGSize pageSize = [document getSizeOfPage:i];
00053         pageOrigin.x = (document.size.width - pageSize.width) / 2;
00054         CGRect pageRect = CGRectMake(pageOrigin.x, pageOrigin.y, pageSize.width, pageSize.height);
00055         pageOrigin.y += pageSize.height;
00056         
00057         // Create an UIImageView object for the page and add it to the container
00058         UIImageView *page = [[UIImageView alloc] initWithImage:placeholder];
00059         page.contentMode = UIViewContentModeCenter;
00060         page.frame = pageRect;        
00061         [container addSubview:page];
00062         [page release];
00063     }
00064     
00065     // Back up zoom scale range
00066     float minimumZoomScale = self.minimumZoomScale;
00067     self.minimumZoomScale = 1.0;
00068     
00069     float maximumZoomScale = self.maximumZoomScale;
00070     self.maximumZoomScale = 1.0;
00071     
00072     // Reset zoom and offset for a clean container resizing experience
00073     self.zoomScale = 1.0;
00074     self.contentOffset = CGPointZero;
00075     
00076     container.frame = CGRectMake(0, 0, document.size.width, document.size.height);
00077     self.contentSize = container.frame.size;
00078     
00079     // Restore zoom scale range
00080     self.minimumZoomScale = minimumZoomScale;
00081     self.maximumZoomScale = maximumZoomScale;
00082     
00083     // Set zoom scale as close to fit-to-width as possible, reset content
00084     // offset for good measure
00085     self.zoomScale = self.bounds.size.width / self.document.size.width;
00086     self.contentOffset = CGPointZero;
00087 }
00088 
00093 - (UIDocument *)document
00094 {
00095     return document;
00096 }
00097 
00106 - (id)init
00107 {
00108     placeholder = nil;
00109     preloadFactor = 0.0;
00110     container = [[UIView alloc] init];
00111     operationQueue = [[NSOperationQueue alloc] init];
00112     // Fast deceleration is best
00113     [self setDecelerationRate:UIScrollViewDecelerationRateFast];
00114     [self addSubview:container];
00115     [super setDelegate:self];
00116     return self;
00117 }
00118 
00124 - (id)initWithDocument:(UIDocument *)uiDocument
00125 {
00126     if((self = [super init])) {
00127         self = [self init];
00128         self.document = uiDocument;
00129     }
00130     return self;
00131 }
00132 
00141 - (id)initWithCoder:(NSCoder *)aDecoder
00142 {
00143     if((self = [super initWithCoder:aDecoder]))
00144         return [self init];
00145     else
00146         return nil;
00147 }
00148 
00155 - (id)initWithFrame:(CGRect)frame
00156 {
00157     if((self = [super initWithFrame:frame]))
00158         return [self init];
00159     else
00160         return nil;
00161 }
00162 
00166 - (void)refresh
00167 {
00168         // Cancel all operations so we don't accidentally load the same page twice
00169         // (this happens anyway at times thanks to parallelism, but this makes it
00170         // less bad.)
00171     [operationQueue cancelAllOperations];
00172     
00173     // Calculate the area the pages intersecting with which are loaded into
00174     // memory
00175     CGRect cacheView = CGRectMake(
00176                                  (self.contentOffset.x - self.bounds.size.width  * preloadFactor) / self.zoomScale,
00177                                  (self.contentOffset.y - self.bounds.size.height * preloadFactor) / self.zoomScale,
00178                                  (self.bounds.size.width  * (2 * preloadFactor + 1)) / self.zoomScale,
00179                                  (self.bounds.size.height * (2 * preloadFactor + 1)) / self.zoomScale
00180                                  );
00181     CGPoint pageOrigin = CGPointZero;
00182     
00183     // Loop through the document's pages
00184     for(int i = 1; i <= document.numberOfPages; ++i) {
00185         // Calculate the frame of the page: horizontally centered and vertically
00186         // directly below the last one
00187         CGSize pageSize = [document getSizeOfPage:i];
00188         pageOrigin.x = (document.size.width - pageSize.width) / 2;
00189         
00190         UIImageView *page = [container.subviews objectAtIndex:i - 1];
00191         CGRect pageRect = CGRectMake(pageOrigin.x, pageOrigin.y, pageSize.width, pageSize.height);
00192         
00193         // Check if the frame of the page intersects with the area to be loaded
00194         // into memory
00195         if(CGRectIntersectsRect(cacheView, pageRect)) {
00196             // Make sure the page image hasn't been loaded already;
00197             // if it hasn't, add a load operation to the queue
00198             if(page.image == placeholder) {
00199                 // Make sure the page image STILL hasn't been loaded into// memory while this operation was sitting in the queue// Load an image into memory and set it as the// page-UIImageView's new image; the setting has to be// done on the main thread so that the OS doesn't// decide to delay it[operationQueue addOperationWithBlock:^{
00200                         
00201                         
00202                     if(page.image == placeholder) {
00203                         
00204                         
00205                         
00206                         
00207                         UIImage *image = [document getImageOfPage:i];
00208                         [page performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
00209                     }
00210                 }];
00211             }
00212         }
00213         else {
00214                 // If the image hasn't been unloaded, do it now. Kind of a
00215                 // redundant check, but it's in place for debugging reasons.
00216             if(page.image != placeholder) {
00217                 page.image = placeholder;
00218             }
00219         }
00220         
00221         // Increment the y coordinate of the origin so that the frame of the
00222         // next page is calculated correctly
00223         pageOrigin.y += pageSize.height;
00224     }
00225 }
00226 
00229 - (void)centerContent
00230 {
00231     // Using container.center didn't work for whatever reason, so this had to
00232     // be done by manually manipulating its frame.
00233     
00234     CGFloat x = 0.0;
00235     if(self.contentSize.width < self.bounds.size.width)
00236         x = (self.bounds.size.width - self.contentSize.width) / 2;
00237     
00238     CGFloat y = 0.0;
00239     if(self.contentSize.height < self.bounds.size.height)
00240         y = (self.bounds.size.height - self.contentSize.height) / 2;
00241     
00242     container.frame = CGRectMake(x, y, container.frame.size.width, container.frame.size.height);
00243 }
00244 
00245 #pragma mark - UIScrollViewDelegate methods for zooming and lazy load.
00246 // These methods are mostly here just to conform to the UIScrollViewDelegate
00247 // protocol and to make the overridden delegate property work properly
00248 
00249 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
00250 {
00251     [self refresh];
00252     
00253         if([delegate respondsToSelector:@selector(scrollViewDidScroll:)])
00254                 [delegate scrollViewDidScroll:scrollView];
00255 }
00256 
00257 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
00258 {
00259     if([delegate respondsToSelector:@selector(viewForZoomingInScrollView:)])
00260         return [delegate viewForZoomingInScrollView:scrollView];
00261     // Zooming only applies to one view object, so it needs to be the container
00262     return container;
00263 }
00264 
00265 - (void)scrollViewDidZoom:(UIScrollView *)scrollView
00266 {
00267     [self centerContent];
00268     
00269     if([delegate respondsToSelector:@selector(scrollViewDidZoom:)])
00270                 [delegate scrollViewDidZoom:scrollView];
00271 }
00272 
00273 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
00274 {
00275         if([delegate respondsToSelector:@selector(scrollViewWillBeginDragging:)])
00276                         [delegate scrollViewWillBeginDragging:scrollView];
00277 }
00278 
00279 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
00280 {
00281         if([delegate respondsToSelector:@selector(scrollViewWillEndDragging:)])
00282                         [delegate scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
00283 }
00284 
00285 - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
00286 {
00287         if([delegate respondsToSelector:@selector(scrollViewShouldScrollToTop:)])
00288                         return [delegate scrollViewShouldScrollToTop:scrollView];
00289     return YES;
00290 }
00291 
00292 - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
00293 {
00294         if([delegate respondsToSelector:@selector(scrollViewDidScrollToTop:)])
00295                         [delegate scrollViewDidScrollToTop:scrollView];
00296 }
00297 
00298 - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
00299 {
00300         if([delegate respondsToSelector:@selector(scrollViewWillBeginDecelerating:)])
00301                         [delegate scrollViewWillBeginDecelerating:scrollView];
00302 }
00303 
00304 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
00305 {
00306         if([delegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)])
00307                         [delegate scrollViewDidEndDecelerating:scrollView];
00308 }
00309 
00310 - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
00311 {
00312         if([delegate respondsToSelector:@selector(scrollViewWillBeginZooming:)])
00313                         [delegate scrollViewWillBeginZooming:scrollView withView:view];
00314 }
00315 
00316 - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
00317 {
00318         if([delegate respondsToSelector:@selector(scrollViewDidEndZooming:)])
00319                         [delegate scrollViewDidEndZooming:scrollView withView:view atScale:scale];
00320 }
00321 
00322 - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
00323 {
00324         if([delegate respondsToSelector:@selector(scrollViewDidEndScrollingAnimation:)])
00325                         [delegate scrollViewDidEndScrollingAnimation:scrollView];
00326 }
00327 
00328 - (void)dealloc
00329 {
00330     [placeholder release];
00331     [container release];
00332     [document release];
00333     [super dealloc];
00334 }
00335 
00336 @end
 All Classes Files Functions Variables Enumerations Enumerator Properties Defines