iOS 에서 pdf를 보여줄때는
UIWebView 또는 UIDocumentInteractionController 를 사용하면 쉽게 구현할수 있다.
근데, 가로스크롤과 페이징이 안된다.
그래서 자료를 찾아보니 애플의 ZoomingPDFView 소스를 보고 분석하면 된다고 한다.
시간이 오래걸릴줄 알고, 맘잡고 시작했는데, 생각보다 금방 끝났다. 3시간 정도...
대부분 무슨뜻인지 잘 모르지만, 그냥 대충 빼껴서 만들었음.


* 먼저 .h 파일
#import <UIKit/UIKit.h>



//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

// 스크롤뷰(좌우) 가지고 있는 뷰컨트롤러

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

@interface PDFViewerVC : UIViewController <UIScrollViewDelegate>

{

  IBOutlet UIScrollView* svPdf;

  IBOutlet UIView* vTop;

  IBOutlet UIView* vBottom;

  IBOutlet UILabel* lblTitle; // 파일명을 보여줄 상단

  IBOutlet UILabel* lblPageNo; // 페이지번호를 보여줄 하단

  

  IBOutlet NSLayoutConstraint* constraintTopViewTop;

  IBOutlet NSLayoutConstraint* constraintBotoomViewBottom;

  

  CGPDFDocumentRef pdfRef;

  CGPDFPageRef pdfPageRef;

  int iPdfPageCount;

  int iPdfPageNo;

  float iPdfScale;

  CGRect rectPdf;

  UITapGestureRecognizer* gestureTap;

}

- (IBAction)doClose:(UIButton*)sender;

@end





//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

// 스크롤뷰안에 들어갈 .

// pdf 한장씩 가지고 있음

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

@interface PDFView : UIView

{

  //CGPDFDocumentRef pdfRef;

  CGPDFPageRef pdfPageRef;

  int iPdfPageCount;

  int iPdfPageNo;

  float iPdfScale;

  //CGRect rectPdf;

}

- (id)initWithFrame:(CGRect)frame withPageNo:(int)i withPdfRef:(CGPDFDocumentRef)pdfRef withScale:(float)scale;

@end







* .m 파일

#import "PDFViewerVC.h"




//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

// 스크롤뷰(좌우) 가지고 있는 뷰컨트롤러

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

@implementation PDFViewerVC



//------------------------------------------------------------------------------

// 초기화

//------------------------------------------------------------------------------

- (void)viewDidLoad

{

  [super viewDidLoad];

  [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;

  

  // Guesture : Tap. 스크롤뷰를 터치하면 상단, 하단 뷰를 보였다 안보였다 하려고

  gestureTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doGuestureTap:)];

  gestureTap.numberOfTouchesRequired = 1;

  gestureTap.numberOfTapsRequired = 1;

  gestureTap.cancelsTouchesInView = NO;

  [svPdf addGestureRecognizer:gestureTap];

  

  

  // pdf 문서의 정보를 가져와서, 총 페이지수를 구한다.

  NSURL* urlLocalPDF = [[NSBundle mainBundle] URLForResource:@"test.pdf" withExtension:nil];

  pdfRef = CGPDFDocumentCreateWithURL( (__bridge CFURLRef) urlLocalPDF );

  iPdfPageCount = CGPDFDocumentGetNumberOfPages(pdfRef);

  

  // 첫번째 페이지를 읽어서, 페이지의 가로세로 크기를 구한다.

  iPdfPageNo = 1;

  pdfPageRef = CGPDFDocumentGetPage(pdfRef, iPdfPageNo);

  

  rectPdf = CGPDFPageGetBoxRect(pdfPageRef, kCGPDFMediaBox);

  iPdfScale = SCREEN_W/rectPdf.size.width;

  rectPdf = CGRectMake(rectPdf.origin.x, rectPdf.origin.y, rectPdf.size.width*iPdfScale, rectPdf.size.height*iPdfScale);


  // pdf 페이지수만큼 뷰를 하나씩 만들어서, 스크롤뷰에 넣는다.

  float iX = 0.0;

  float iY = (SCREEN_H-20.0-rectPdf.size.height)/2.0;

  for(int i=0; i<iPdfPageCount; i++)

  {

    CGRect f = CGRectMake(iX, -iY, SCREEN_W, SCREEN_H-20.0);

    PDFView* pdfView = [[PDFView alloc] initWithFrame:f

                                           withPageNo:i+1

                                           withPdfRef:pdfRef

                                            withScale:iPdfScale];

    [svPdf addSubview:pdfView];

    

    iX += SCREEN_W;

  }

  

  svPdf.contentSize = CGSizeMake(iX, SCREEN_H-20.0);

  svPdf.delegate = self;

  lblPageNo.text = [NSString stringWithFormat:@"(1/%d)", iPdfPageCount];

}



//------------------------------------------------------------------------------

// close

//------------------------------------------------------------------------------

- (IBAction)doClose:(UIButton*)sender

{

  [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

  [self dismissViewControllerAnimated:YES completion:nil];

}



//------------------------------------------------------------------------------

// Tap gesture.

//------------------------------------------------------------------------------

- (void)doGuestureTap:(UITapGestureRecognizer*)tap

{

  vTop.hidden = !vTop.hidden;

  vBottom.hidden = !vBottom.hidden;

}





#pragma mark - UIScrollViewDelegate delete method


//------------------------------------------------------------------------------

// 스크롤시, 페이지번호 보여줌

//------------------------------------------------------------------------------

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

{

  int i = scrollView.contentOffset.x / scrollView.frame.size.width;

  lblPageNo.text = [NSString stringWithFormat:@"(%d/%d)", i+1, iPdfPageCount];

}



#pragma mark -

- (void)didReceiveMemoryWarning

{

  [super didReceiveMemoryWarning];

}


@end





//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

// 스크롤뷰안에 들어갈 .

// pdf 한장씩 가지고 있음

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

@implementation PDFView



//------------------------------------------------------------------------------

//

//------------------------------------------------------------------------------

+ (Class)layerClass

{

  return [CATiledLayer class];

}



//------------------------------------------------------------------------------

//

//------------------------------------------------------------------------------

- (id)initWithFrame:(CGRect)frame withPageNo:(int)i withPdfRef:(CGPDFDocumentRef)pdfRef withScale:(float)scale

{

  self = [super initWithFrame:frame];

  if(self == nil) return self;

  

  iPdfPageNo = i;

  iPdfScale = scale;

  pdfPageRef = CGPDFDocumentGetPage(pdfRef, iPdfPageNo);

  

  CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];

  tiledLayer.levelsOfDetail = 4;

  tiledLayer.levelsOfDetailBias = 3;

  tiledLayer.tileSize = CGSizeMake(512.0, 512.0);

  

  return self;

}



//------------------------------------------------------------------------------

// Draw the CGPDFPageRef into the layer at the correct scale.

//------------------------------------------------------------------------------

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context

{

  // Fill the background with white.

  CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);

  CGContextFillRect(context, self.bounds);

    

  // Print a blank page and return if our page is null.

  if( pdfPageRef == NULL ) return;

  

  CGContextSaveGState(context);

  

  // Flip the context so that the PDF page is rendered right side up.

  CGContextTranslateCTM(context, 0.0, self.bounds.size.height);

  CGContextScaleCTM(context, 1.0, -1.0);

  

  // Scale the context so that the PDF page is rendered at the correct size for the zoom level.

  CGContextScaleCTM(context, iPdfScale, iPdfScale);

  

  CGContextDrawPDFPage(context, pdfPageRef);

  CGContextRestoreGState(context);

}



@end



반응형

'iOS 초보' 카테고리의 다른 글

CoreBluetooth 기본  (0) 2015.05.21
2.23리젝 대응  (0) 2015.05.12
perform block with delay  (0) 2015.04.28
status bar 객체 얻기  (0) 2015.04.07
UIActivityViewController, 카카오링크 연동  (0) 2015.04.03
Posted by 돌비
,