简体   繁体   English

当我在ipad屏幕上触摸时如何获得PDF注释

[英]How to get PDF annotations when i touch on ipad screen

I have developed an application which displays PDF on ipad using CATiled Layer. 我开发了一个应用程序,它使用CATiled Layer在ipad上显示PDF。 So far, so good& But there is a problem which really makes me cut my last hairs. 到目前为止,这么好&但有一个问题真的让我削减了我的最后一根头发。 I have a PDF with embedded annotations. 我有一个嵌入了注释的PDF。 Each annotation has an URL. 每个注释都有一个URL。 I can find the coordinates of touch area but the question is how I can find if there is an annotation under my finger and how to extract URL to open it in browser? 我可以找到触摸区域的坐标,但问题是如果我的手指下有注释以及如何提取URL以在浏览器中打开它,我怎么能找到?

If anyone can share any thoughts about how this can be done, I will really appreciate your help! 如果有人可以分享有关如何做到这一点的任何想法,我将非常感谢您的帮助!

Thanks in advance 提前致谢

Getting the annotations isn't very difficult with CGPDF although it required a little fiddling around for me at first. 使用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;
    }

This will get you the URLs. 这将为您提供URL。 Getting the rects: 获得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]];
    }

As you can see this bit of code first gets the rectangle of the annotation, transforms it to the device coordinate system, then does some recalculation, sizing and repositioning, based on page to screen ratio, rotation factor, etc. At the end you will have an array of the touch-active areas for that page. 正如您所看到的,这段代码首先获取注释的矩形,将其转换为设备坐标系,然后根据页面到屏幕的比例,旋转因子等进行一些重新计算,调整大小和重新定位。最后,您将有一个该页面的触摸活动区域的数组。 For handling the touches the following simple solution can be used: 为了处理触摸,可以使用以下简单的解决方案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我在iPhone / iPad中触摸MKMapView时,如何获取经纬度之类的信息? - How can i get any information like lat,long when i touch on MKMapView in iPhone/iPad? 我在iOS中触摸屏时如何隐藏键盘 - how to hide keyboard when i touch screen in iOS 在构建触摸键盘时,如何在ipad上支持可连接的键盘? - How do I support an attachable keyboard on ipad when building a touch keypad? 如何获得不同方向的iPad屏幕尺寸? - How to get iPad screen size in different orientations? Touch ID - 如何进入密码屏幕? -迅速 - Touch ID - How to get to the passcode screen? -Swift 在iPad屏幕上检测手触摸事件 - Detecting Hand touch event on iPad screen 使用UITouch时如何获得触摸偏移 - How can I get touch offset when using UITouch 如何获得关于iPad屏幕的popoverview内txtfield的位置 - How do I get the position of a txtfield inside a popoverview with respect to ipad screen 当我在iPad上运行iPhone应用程序时,屏幕分辨率是错误的。 如何解决这个问题? - When I run iPhone app on iPad the screen resolution is wrong. How to fix this? 当我缩放mapView以显示注释时,所选注释部分不在屏幕上 - When I zoom my mapView to show my annotations, the selected annotations are partially off screen
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM