@end
@interface ThumbnailScrollView : UIScrollView
- (ThumbnailScrollView *)initWithWebView:(UIWebView *)superview height:(float)height;
- (void)addThumbnailViews:(NSData *)pdfData;
- (void)setPdfThumbnailImage:(NSData *)pdfData;
@end
@implementation ThumbnailScrollView
{
//イメージセットが完了するまで保持する。
CGPDFDocumentRef _pdf;
}
//保持していた_pdfをreleaseする。
//setPdfThumbnailImageでイメージセット完了時にも実行しているが、
//その前にdeallocされる可能性があるのでここでも実行する。
- (void)dealloc
{
if (_pdf) CGPDFDocumentRelease(_pdf);
_pdf = nil;
}
//superviewにUIScrollViewを追加。frameはsuperviewに合わせて設定する。
- (ThumbnailScrollView *)initWithWebView:(UIWebView *)webView height:(float)height
{
//画面下10pt上の位置に設定。高さはパラメータの値、幅はsuperviewと同じ。
CGRect r = CGRectMake(0, webView.frame.size.height - height - 10,
webView.frame.size.width, height);
self = [super initWithFrame:r];
if (self) {
[webView addSubview:self];
}
return self;
}
//ScrollView内に、PDFページに対応するThumbnailImageViewを配置する。
//ここではまだイメージはセットしないが、矩形領域は表示されるようになる。
- (void)addThumbnailViews:(NSData *)pdfData
{
CGDataProviderRef provider =
CGDataProviderCreateWithCFData((__bridge CFDataRef)pdfData);
_pdf = CGPDFDocumentCreateWithProvider(provider);
//providerは同じメソッド内でreleaseしないとメモリリークの原因になる。
CFRelease(provider);
int numPages = CGPDFDocumentGetNumberOfPages(_pdf);
float x = 10;
float h = self.frame.size.height;
float pagePos = 0;
UIScrollView *webScrollView = ((UIWebView *)self.superview).scrollView;
for (int p = 1; p <= numPages; p++) {
//CGPDFPageRefはautoreleaseされるのでreleaseする必要なし。
CGPDFPageRef pageRef = CGPDFDocumentGetPage(_pdf, 1);
CGRect pageRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox);
float w = pageRect.size.width * (h / pageRect.size.height);
CGRect imageRect = CGRectMake(x, 0, w, h);
ThumbnailImageView *v = [[ThumbnailImageView alloc] initWithFrame:imageRect pageNum:p pagePos:pagePos];
v.alpha = 0.5;
[self addSubview:v];
//タップ時のアクションをセット
[v addTarget:self action:@selector(jumpToPage:) forControlEvents:UIControlEventTouchUpInside];
x += w + 10; //サムネイル間に10ptの間隔を置く。
pagePos += pageRect.size.height * (webScrollView.frame.size.width-5) / pageRect.size.width;
//contentSize調整
self.contentSize = CGSizeMake(self.contentSize.width + w + 10, self.contentSize.height);
}
[self setNeedsDisplay];
}
//配置したThumbnailImageViewにイメージをセット
- (void)setPdfThumbnailImage:(NSData *)pdfData
{
size_t numPages = CGPDFDocumentGetNumberOfPages(_pdf);
for(int p=1; p<=numPages; p++) {
CGPDFPageRef pageRef = CGPDFDocumentGetPage(_pdf, p);
ThumbnailImageView *v = [self.subviews objectAtIndex:p-1];
[v setImageWithPdfPage:pageRef];
}
//ループが無事完了したら_pdfをリリース
CGPDFDocumentRelease(_pdf);
_pdf = nil;
[self setNeedsDisplay];
}
//タップされたサムネールのページ位置に移動
- (void)jumpToPage:(ThumbnailImageView *)sender
{
UIScrollView *scrollView = ((UIWebView *)self.superview).scrollView;
CGPoint point = CGPointMake(0, sender.pagePos * scrollView.zoomScale);
[scrollView setContentOffset:point animated:YES];
}
@end