当我触摸iPad屏幕时如何获得PDF注释

我开发了一个应用程序,使用CATiled Layer在ipad上显示PDF。 到目前为止,这么好&但有一个问题,真的让我削减我最后的头发。 我有一个PDFembedded注释。 每个注释都有一个URL。 我可以find触摸区域的坐标,但问题是如何find我的手指下是否有注释以及如何提取URL以在浏览器中打开它?

如果任何人可以分享任何想法如何做到这一点,我会非常感谢您的帮助!

提前致谢

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; } 

这会得到你的url。 获得反思:

 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]]; } 

正如你所看到的,这个代码首先得到注解的矩形,把它转换到设备坐标系统,然后根据页面到屏幕的比例,旋转因子等做一些重新计算,大小和重新定位。最后你会有一个该页面的触控区域arrays。 为了处理触摸,可以使用以下简单的解决scheme:

 - (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)); } }