views:

609

answers:

3

Hello I want to make an application in which I have to display pdffile on iphone screen, which has a functionality of zooming. I have multiple pages of pdffile, but the problem is i can get display only one page. Here is the code :

/*myView.m*/

@implementation MyView

- (void)configureTiledLayer {

    if([global  getfirsttime] == 0)
    {

     [global fetchpageCtr : 1];
     [global fetchfirsttime:1];
    }

  zoom = 1.0f;

  tiledLayer = [CATiledLayer layer];
  TiledDelegate *delegate = [[TiledDelegate alloc] init];
  tiledLayer.delegate = delegate;
  // get tiledLayer size
  CGRect pageRect = CGPDFPageGetBoxRect(delegate.map, kCGPDFCropBox);
  int w = pageRect.size.width;
  int h = pageRect.size.height;


    NSLog(@"height==%d,weight=%d",h,w);
  // get level count
  int levels = 1;
  while (w > 1 && h > 1) {
    levels++;
    w = w >> 1;
    h = h >> 1;
  }


    NSLog(@"Layer create");

  // set the levels of detail
  tiledLayer.levelsOfDetail = levels;
  // set the bias for how many 'zoom in' levels there are
  tiledLayer.levelsOfDetailBias = 5;
  // setup the size and position of the tiled layer
     CGFloat width = CGRectGetWidth(pageRect);
     CGFloat height = CGRectGetHeight(pageRect);
  tiledLayer.bounds = CGRectMake(0.0f, 0.0f, width, height);
  CGFloat x = width * tiledLayer.anchorPoint.x;
  CGFloat y = -height * tiledLayer.anchorPoint.y;
  tiledLayer.position = CGPointMake(x * zoom, y * zoom);
  tiledLayer.transform = CATransform3DMakeScale(zoom, zoom, 1.0f);

  // transform the super layer so things draw 'right side up'
  CATransform3D superTransform = CATransform3DMakeTranslation(0.0f, self.bounds.size.height, 0.0f);
  self.layer.transform = CATransform3DScale(superTransform, 1.0, -1.0f, 1.0f);

  [self.layer addSublayer:tiledLayer];


  [tiledLayer setNeedsDisplay];
  moving = NO;

    NSLog(@"in layer");
}  

- (id)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
      self.backgroundColor = [UIColor blueColor];
    [self configureTiledLayer];
  }
  return self;
}

- (id)initWithCoder:(NSCoder *)coder {
  if (self = [super initWithCoder:coder]) {


    [self configureTiledLayer];

  }
  return self;
}

- (void)setZoom:(CGFloat)newZoom {
  zoom = newZoom;
  tiledLayer.transform = CATransform3DMakeScale(zoom, zoom, 1.0f);
}

- (void)zoomIn {
  [self setZoom:zoom * 2.0f];
}

- (void)zoomOut {
  [self setZoom:zoom * 0.5f];
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  if(touches.count == 1) {
    previousPoint = [[touches anyObject] locationInView:self];
  } else if(touches.count == 2) {
    // pinch zoom
    pinchZoom = YES;
    NSArray *touches = [event.allTouches allObjects];
    CGPoint pointOne = [[touches objectAtIndex:0] locationInView:self];
    CGPoint pointTwo = [[touches objectAtIndex:1] locationInView:self];
    previousDistance = sqrt(pow(pointOne.x - pointTwo.x, 2.0f) + 
                            pow(pointOne.y - pointTwo.y, 2.0f));
  }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  if(touches.count == 1) {
    CGPoint currentPoint = [[touches anyObject] locationInView:self];
    CGPoint delta = CGPointMake(currentPoint.x - previousPoint.x, currentPoint.y - previousPoint.y);
    tiledLayer.position = CGPointMake(tiledLayer.position.x + delta.x * zoom,
                                      tiledLayer.position.y + delta.y * zoom);
    previousPoint = currentPoint;
    moving = YES;
  } else if(touches.count == 2) {
    // pinch zoom stuff
    NSArray *touches = [event.allTouches allObjects];
    CGPoint pointOne = [[touches objectAtIndex:0] locationInView:self];
    CGPoint pointTwo = [[touches objectAtIndex:1] locationInView:self];
    CGFloat distance = sqrt(pow(pointOne.x - pointTwo.x, 2.0f) + 
                            pow(pointOne.y - pointTwo.y, 2.0f));
    CGFloat newZoom = fabs(zoom + (distance - previousDistance) / previousDistance);
    [self setZoom:newZoom];
    previousDistance = distance;
  }
}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  if(!moving) {
    if(touches.count == 1) {
      // realy should recenter on a click but I'm being lazy
      if([[touches anyObject] tapCount] == 2) {
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
        [self zoomOut];
      } else {
        [self performSelector:@selector(zoomIn) withObject:nil afterDelay:0.25];
      }
    }
  } else {
    moving = NO;
  }
}

- (void)dealloc {
  [tiledLayer release];
  [super dealloc];
}

/*TiledDelegate.m*/
@implementation TiledDelegate

- (CGPDFDocumentRef)sfMuni {
  if(NULL == sfMuni) {


    NSString *path = [[NSBundle mainBundle] pathForResource:@"Hunting-TrappingSynopsis_0910" ofType:@"pdf"];
    NSURL *docURL = [NSURL fileURLWithPath:path];
    sfMuni = CGPDFDocumentCreateWithURL((CFURLRef)docURL);
  }
  return sfMuni;
}

- (CGPDFPageRef)map {

    int temppageno  = [global getpageCtr];

    NSLog(@"page ctr ==%d ",temppageno);

    if(NULL == map) {
     map = CGPDFDocumentGetPage(self.sfMuni, temppageno);
    }
    return map;
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
  NSLog(@"\ndrawLayer:inContext:");
  NSLog(@"ctm = %@", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
  NSLog(@"box = %@\n", NSStringFromCGRect(CGContextGetClipBoundingBox(ctx)));
  CGContextDrawPDFPage(ctx, self.map);


}

- (void)dealloc {
  CGPDFPageRelease(map);
  CGPDFDocumentRelease(sfMuni);
  [super dealloc];
}

/*TiledLayerAppDelegate*/
- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}


- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}

/*TiledLayerViewController*/

- (void)viewDidLoad 
{

    l_pagectr = 2;

    UIButton *btn1 = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
    btn1.frame = CGRectMake(0,0,70,50);
    [btn1 setBackgroundColor: [UIColor whiteColor]];
    btn1.exclusiveTouch = YES;
    [btn1 setTitle:@"Next" forState:UIControlStateNormal];
    [btn1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn1 addTarget:self action:@selector(NextPressed:)
   forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn1];



}


-(IBAction)NextPressed : (id)sender
{

    [global fetchpageCtr : l_pagectr++];



    MyView *myview1=[[MyView alloc]init];

}
@end

Here when I pressed Next button it will have to display me the nest page but will display me the same page.I also get the page referance in "CGPDFPageRef" incremented but not displayed.

Plz help me for this.

+2  A: 

Why don't you just use UIWebView? It renders PDF and offers zoom controls. No need to reinvent the wheel. Here is documentation for UIWebView.

Alex Reynolds
This does have a couple drawbacks, though. One, it requires a lot more overhead than what he seems to need, and two, it treads dangerously close to the feature region where Apple will make you slap a 17+ rating on your app because it might let someone get on the Web.
Gordon Worley
If you are only displaying PDF's without links there is no danger of getting the 17+ rating. Plenty of apps use UIWebViews for formatted text displays for example, with no such restriction or rating.
Kendall Helmstetter Gelner
A: 

I have a full-writeup coming of how I've done this - though I'm currently dealing with jumpiness issues with touch scrolling... let me know if you are still having this problem an I'll post it here...

Jared
A: 

I have a full-writeup coming of how I've done this - though I'm currently dealing with jumpiness issues with touch scrolling... let me know if you are still having this problem an I'll post it here...

I would like to see your solution please. :P

Jerry