2011-03-18 143 views
5

我開發了一個應用程序,它使用CATiled Layer在ipad上顯示PDF。到目前爲止,這麼好&但是有一個問題真的讓我削減了我最後的頭髮。我有一個帶有嵌入註釋的PDF。每個註釋都有一個URL。我可以找到觸摸區域的座標,但問題是如何找到我的手指下是否有註釋以及如何提取URL以在瀏覽器中打開它?如何獲得PDF註釋,當我觸摸在ipad屏幕上

如果任何人都可以分享任何關於如何做到這一點的想法,我將非常感謝您的幫助!

在此先感謝

+0

溶液使用石英:http://stackoverflow.com/questions/4080373/get-pdf-hyperlinks-on-ios-with-quartz 希望這幫助 – AmineG 2011-06-10 22:12:00

回答

6

獲取註釋不符合CGPDF非常困難的,雖然它需要一點點擺弄周圍,我在第一。

//Get the current page ref 
CGPDFPageRef currentPdfPage = CGPDFDocumentGetPage(pdfDocumentRef, page); 

//Get the page dictionary 
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(currentPdfPage); 
CGPDFArrayRef annotsArray; 

//Get the Annots array 
if(!CGPDFDictionaryGetArray(pageDictionary, "Annots", &annotsArray)) { 
    //DLog(@"No Annots found for page %d", page); 
    [self updateProgress]; 
    return; 
} 

int annotsArrayCount = CGPDFArrayGetCount(annotsArray); 
//DLog(@"%d annots found for page %d in file %@", annotsArrayCount, page, _fileName); 
NSMutableArray* touchRectsArray = [[NSMutableArray alloc] initWithCapacity:annotsArrayCount]; 
for (int j=annotsArrayCount; j >= 0; j--) { 
    int destPageNumber = 0; 
    NSString* uri = nil; 

    //DLog(@"%d/%d", j+1, annotsArrayCount); 

    CGPDFObjectRef aDictObj; 
    if(!CGPDFArrayGetObject(annotsArray, j, &aDictObj)) { 
     //DLog(@"%@", @"can't get dictionary object"); 
     continue; 
    } 

    CGPDFDictionaryRef annotDict; 
    if(!CGPDFObjectGetValue(aDictObj, kCGPDFObjectTypeDictionary, &annotDict)) { 
     //DLog(@"%@", @"can't get annotDict"); 
     continue; 
    } 

    //------------ 
    CGPDFDictionaryRef aDict; 
    CGPDFArrayRef destArray; 
    if(CGPDFDictionaryGetDictionary(annotDict, "A", &aDict)) { 
     CGPDFStringRef uriStringRef; 
     if(CGPDFDictionaryGetString(aDict, "URI", &uriStringRef)) { 
      char* uriString = (char *)CGPDFStringGetBytePtr(uriStringRef); 
      uri = [NSString stringWithCString:uriString encoding:NSUTF8StringEncoding]; 
     } 
    } else { 
     continue; 
    } 

這會爲您提供網址。 獲取rects:

CGPDFArrayRef rectArray; 
    if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) { 
     DLog(@"%@", @"can't get Rect"); 
    } 

    int arrayCount = CGPDFArrayGetCount(rectArray); 
    CGPDFReal coords[4]; 
    for (int k = 0; k < arrayCount; k++) { 
     CGPDFObjectRef rectObj; 
     if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) { 
      DLog(@"%@", @"can't get rect data"); 
     } 

     CGPDFReal coord; 
     if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) { 
      DLog(@"%@", @"can't get coords"); 
     } 

     coords[k] = coord; 
    } 

    CGRect drawRect = [[SharedConfig valueForKey:@"screenSize"] CGRectValue]; 
    BOOL drawBoxIsLandscape = NO; 
    if (1 < drawRect.size.width/drawRect.size.height) { 
     drawBoxIsLandscape = YES; 
    } 

    CGRect pageRect = CGRectIntegral(CGPDFPageGetBoxRect(currentPdfPage, kCGPDFMediaBox)); 
    landscape = NO; 
    if (1 < pageRect.size.width/pageRect.size.height) { 
     landscape = YES; 
    } 

    float ratio = 0.0; 

    //Get the rect of the clickable area 
    //CGRect coordsRect = CGRectMake(coords[0], coords[1], coords[2], coords[3]); 
    //Transform to new coordinate system 
    CGRect originalRect = CGRectMake(coords[0], (pageRect.size.height-(coords[3]-coords[1]))-coords[1], coords[2]-coords[0], coords[3]-coords[1]); 

    CGPDFInteger pageRotate = 0; 
    CGPDFDictionaryGetInteger(pageDictionary, "Rotate", &pageRotate); 

    if (pageRotate == 90 || pageRotate == 270) { 
     CGFloat temp = pageRect.size.width; 
     pageRect.size.width = pageRect.size.height; 
     pageRect.size.height = temp; 
     ratio = drawRect.size.height/pageRect.size.height; 
    }  

    if (drawBoxIsLandscape) { 
     ratio = landscape ? (drawRect.size.height/pageRect.size.height) : (drawRect.size.height/pageRect.size.width); 

     if (landscape && drawRect.size.width < pageRect.size.width*ratio) { 
      ratio = drawRect.size.width/pageRect.size.width; 
     } else if (!landscape && drawRect.size.height < pageRect.size.width*ratio) { 
      ratio = drawRect.size.height/pageRect.size.width; 
     } 
    } else { 
     ratio = landscape ? (drawRect.size.height/pageRect.size.width) : (drawRect.size.height/pageRect.size.height); 

     if (landscape && drawRect.size.width < pageRect.size.height*ratio) { 
      ratio = drawRect.size.width/pageRect.size.height; 
     } else if (!landscape && drawRect.size.height < pageRect.size.height*ratio) { 
      ratio = drawRect.size.height/pageRect.size.height; 
     } 
    } 

    CGRect calculatedRect = CGRectMake(originalRect.origin.x*ratio, originalRect.origin.y*ratio, originalRect.size.width*ratio, originalRect.size.height*ratio); 

    if ((landscape && !drawBoxIsLandscape) || (!landscape && drawBoxIsLandscape)) { 
     CGFloat width = calculatedRect.size.width; 
     calculatedRect.size.width = calculatedRect.size.height; 
     calculatedRect.size.height = width; 

     CGFloat yModifier = drawRect.size.height-(pageRect.size.width*ratio); 

     CGFloat x = calculatedRect.origin.x; 
     calculatedRect.origin.x = calculatedRect.origin.y; 
     calculatedRect.origin.y = drawRect.size.height-(x+calculatedRect.size.height)-yModifier; 

    } 

    if (nil != uri) { 
     [touchRectsArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithCGRect:calculatedRect], @"rect", uri, @"targetUrl", nil]]; 
    } 

正如你所看到的這段代碼首先獲得註釋的矩形,將其轉換爲設備座標系統,然後做一些重新計算,大小和重新定位,立足於屏幕頁面上比率,旋轉因子等。最後,您將擁有該頁面的觸控區域陣列。用於處理觸摸以下簡單的解決方案可以用於:

- (void) tapGesture:(UIGestureRecognizer*)sender 
{ 
if (UIGestureRecognizerStateEnded == sender.state) { 
    CGPoint touchPoint = [sender locationInView:self.view]; 

    if (nil != self.touchRects) for (int i=0; i<[self.touchRects count]; i++) { 
     if (CGRectContainsPoint([[[self.touchRects objectAtIndex:i] objectForKey:@"rect"] CGRectValue], touchPoint)) { 
      if ([[self.touchRects objectAtIndex:i] objectForKey:@"targetUrl"]) { 
       NSString* targetUrl = [[self.touchRects objectAtIndex:i] objectForKey:@"targetUrl"]; 
       DLog(@"Hit found for target url: %@", targetUrl); 
       NSURL* url = [NSURL URLWithString:targetUrl]; 
       [[UIApplication sharedApplication] openURL:url]; 
      }    return; 
     }  
    } 
    DLog(@"No hit found for touch at %@", NSStringFromCGPoint(touchPoint)); 
} 
} 
+0

感謝您的詳細解答,我已經設法解決我的問題了。我注意到你正在使用MediaBox來獲得pdf頁面。我使用CropBox,它使事情變得複雜一點... – Adviser2010 2011-07-04 03:59:21

相關問題