2
votes

I'm currently using a bit of modified code from Get PDF hyperlinks on iOS with Quartz to search for annotations in a pdf and then placing buttons over them for navigation. It's currently passing the whole pdf where as I would like it just to pass the current page and place buttons for the annotations on that page. I've gone over the documentation which is pretty hopeless on this subject and been playing around with it for a day or so but no luck.

I'm sure I'm missing something stupid so any help would be much appreciated.

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:(CGRect)frame];
    if (self) {
        self.backgroundColor = [UIColor clearColor];
        NSString *pathToPdfDoc = [[NSBundle mainBundle] pathForResource:@"testpdf" ofType:@"pdf"];
        NSURL *pdfUrl = [NSURL fileURLWithPath:pathToPdfDoc];
        document = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl);
        currentPage = 1;
    }
    return self;
}

-(void)drawRect:(CGRect)inRect{
    if(document) {
        CGPDFPageRef page = CGPDFDocumentGetPage(document, currentPage);
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGContextSaveGState(ctx);
        CGContextTranslateCTM(ctx, 0.0, [self bounds].size.height);
        CGContextScaleCTM(ctx, 1.0, -1.0);
        CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, [self bounds], 0, true));
        CGContextDrawPDFPage(ctx, page);    
        CGContextRestoreGState(ctx);
        int pageCount = CGPDFDocumentGetNumberOfPages (document);

        for(i=0; i<=currentPage; i++) {
            CGPDFPageRef page = CGPDFDocumentGetPage(document, i+1);

            CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(page);

            CGPDFArrayRef outputArray;
            if(!CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)) {
                break;
            }

            int arrayCount = CGPDFArrayGetCount( outputArray );
            if(!arrayCount) {
                continue;
            }
            for( int j = 0; j < arrayCount; ++j ) {
                CGPDFObjectRef aDictObj;
                if(!CGPDFArrayGetObject(outputArray, j, &aDictObj)) {
                    break;
                }
                NSLog(@"poop2");
                CGPDFDictionaryRef annotDict;
                if(!CGPDFObjectGetValue(aDictObj, kCGPDFObjectTypeDictionary, &annotDict)) {
                    break;
                }
                CGPDFDictionaryRef aDict;
                if(!CGPDFDictionaryGetDictionary(annotDict, "A", &aDict)) {
                    break;
                }                
                CGPDFStringRef uriStringRef;
                if(!CGPDFDictionaryGetString(aDict, "URI", &uriStringRef)) {
                    break; 
                }                
                CGPDFArrayRef rectArray;
                if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) {
                    break;
                }
                int arrayCount = CGPDFArrayGetCount( rectArray );
                CGPDFReal coords[4];
                for( int k = 0; k < arrayCount; ++k ) {
                    CGPDFObjectRef rectObj;
                    if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) {
                        break;
                    }
                    CGPDFReal coord;
                    if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) {
                        break;
                    }
                    coords[k] = coord;
                }           
                char *uriString = (char *)CGPDFStringGetBytePtr(uriStringRef);
                NSString *uri = [NSString stringWithCString:uriString encoding:NSUTF8StringEncoding];
                if (950 <= coords[3] && coords[3] < 1000){                    
                    coords[3]= (coords[3]*1.01);
                    coords[1]= (coords[1]*1.01)-10;
                }
                else if (900 <= coords[3] && coords[3] < 949){                    
                    coords[3]= (coords[3]*1.02);
                    coords[1]= (coords[1]*1.02)-10;
                }
                else if (850 <= coords[3] && coords[3] < 899){                    
                    coords[3]= (coords[3]*1.03);
                    coords[1]= (coords[1]*1.03)-10;
                }                
                else if (800 <= coords[3] && coords[3] < 849){                    
                    coords[3]= (coords[3]*1.035);
                    coords[1]= (coords[1]*1.035)-10;
                }                
                else if (750 <= coords[3] && coords[3] < 799){                    
                    coords[3]= (coords[3]*1.04);
                    coords[1]= (coords[1]*1.04)-10;
                }
                else if (700 <= coords[3] && coords[3] < 749){                    
                    coords[3]= (coords[3]*1.05);
                    coords[1]= (coords[1]*1.05)-10;
                }
                else if (650 <= coords[3] && coords[3] < 699){                    
                    coords[3]= (coords[3]*1.06);
                    coords[1]= (coords[1]*1.06)-10;
                }
                else if (600 <= coords[3] && coords[3] < 649){                    
                    coords[3]= (coords[3]*1.075);
                    coords[1]= (coords[1]*1.075)-10;
                }                
                else if (550 <= coords[3] && coords[3] < 599){                    
                    coords[3]= (coords[3]*1.09);
                    coords[1]= (coords[1]*1.09)-10;
                }
                else if (500 <= coords[3] && coords[3] < 549){                    
                    coords[3]= (coords[3]*1.1);
                    coords[1]= (coords[1]*1.1)-10;
                }
                else if (450 <= coords[3] && coords[3] < 499){                    
                    coords[3]= (coords[3]*1.13);
                    coords[1]= (coords[1]*1.13)-10;
                }
                else if (400 <= coords[3] && coords[3] < 449){                    
                    coords[3]= (coords[3]*1.15);
                    coords[1]= (coords[1]*1.15)-10;
                }
                else if (300 <= coords[3] && coords[3] < 399){                    
                    coords[3]= (coords[3]*1.18);
                    coords[1]= (coords[1]*1.18)-10;
                }
                else if (250 <= coords[3] && coords[3] < 299){
                    coords[3]= (coords[3]*1.30);
                    coords[1]= (coords[1]*1.30)-10;
                }
                else if (200 <= coords[3] && coords[3] < 249){
                    coords[3]= (coords[3]*1.4);
                    coords[1]= (coords[1]*1.4)-10;
                }
                else if (150 <= coords[3] && coords[3] < 199){
                    coords[3]= (coords[3]*1.6);
                    coords[1]= (coords[1]*1.6)-10;
                }
                else if (100 <= coords[3] && coords[3] < 149){
                    coords[3]= (coords[3]*1.8);
                    coords[1]= (coords[1]*1.8)-10;
                }
                else if (50 <= coords[3] && coords[3] < 99){
                    coords[3]= (coords[3]*2);
                    coords[1]= (coords[1]*2)-10;
                }
                else if (0 <= coords[3] && coords[3] < 49){
                    coords[3]= (coords[3]*2.5);
                    coords[1]= (coords[1]*2.5-10);
                }
                CGRect rect = CGRectMake(coords[0] /1.11, coords[1],coords[2],coords[3]);
                CGPDFInteger pageRotate = 0;
                CGPDFDictionaryGetInteger( pageDictionary, "Rotate", &pageRotate ); 
                CGRect pageRect = CGRectIntegral( CGPDFPageGetBoxRect( page, kCGPDFMediaBox ));
                if( pageRotate == 90 || pageRotate == 270 ) {
                    CGFloat temp = pageRect.size.width;
                    pageRect.size.width = pageRect.size.height;
                    pageRect.size.height = temp;
                }
                rect.size.width -= rect.origin.x;
                rect.size.height -= rect.origin.y;
                CGAffineTransform trans = CGAffineTransformIdentity;
                trans = CGAffineTransformTranslate(trans, 0, pageRect.size.height);
                trans = CGAffineTransformScale(trans, 1.0, -1.0);
                rect = CGRectApplyAffineTransform(rect, trans);
                // do whatever you need with the coordinates.
                // e.g. you could create a button and put it on top of your page
                // and use it to open the URL with UIApplication's openURL
                url = [NSURL URLWithString:uri];
                CGPDFContextSetURLForRect(ctx, (CFURLRef)url, rect);
                buttonArray = [[NSMutableArray alloc] init];
                for(NSInteger b = 0; b < CGPDFArrayGetCount(outputArray); b++){
                    button = [[UIButton alloc] initWithFrame:rect];
                    [button setTitle:@"" forState:UIControlStateNormal];
                    [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
                    [button setBackgroundColor:[UIColor blueColor]];
                    [button.titleLabel setBackgroundColor:[UIColor clearColor]];
                    button.tag = currentPage;
                    [button addTarget:self action:@selector(openLink:) forControlEvents:UIControlEventTouchUpInside];
                    [self addSubview:button];
                    [buttonArray addObject:button];
                }
                NSLog(@"%i", CGPDFArrayGetCount(buttonArray));                
            }
        }   
    }   
}
1

1 Answers

2
votes

So this line:

for(i=0; i<=currentPage; i++) {

Is looping (iterating) over all of the pages from the first page to the current page. You should remove that loop (with the associated }) and then change this line:

CGPDFPageRef page = CGPDFDocumentGetPage(document, i+1);

to this

CGPDFPageRef page = CGPDFDocumentGetPage(document, currentPage);

You set currentPage as 1 in the initWithFrame. This will get you the current page.