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 |