iOS11 PDFKit

2017-10-12  本文已影响779人  KeepFighting

PDFDocument就等同 PDF文件,需要借助PDFView显示出来

- (void)createDocument {
    NSString *pdfPath = [[NSBundle mainBundle] pathForResource:@"Sample.pdf" ofType:nil];
    NSURL * url = [NSURL fileURLWithPath:pdfPath];
    PDFDocument *document =[ [PDFDocument alloc] initWithURL:url];
    if (document) {
        self.pdfView.document = document;
        self.pdfView.autoScales = YES;
        self.pdfView.backgroundColor = [UIColor lightGrayColor];
    }
}

显示模式有4种
singlePage:单页显示,滚动只影响当前页
singlePageContinuous :显示全部页面,默认垂直排列
twoUp: 双页显示,滚动只影响当前2页
twoUpContinuous: 显示所有页,双页显示
滚动方向:水平和垂直

 self.pdfView.displayMode = kPDFDisplayTwoUpContinuous;
self.pdfView.displayDirection = kPDFDisplayDirectionVertical;

PDF的每一页由PDFPage类管理

- (void)createThumbnails {
    PDFPage *page =  [self.document pageAtIndex:0];
    CGSize size = CGSizeMake(300, 300);
    UIImage *image = [page thumbnailOfSize:size forBox:kPDFDisplayBoxCropBox];
    UIImageView * imageview = [[UIImageView alloc] initWithImage:image];
    imageview.frame = CGRectMake(10, 200, 300, 300);
    [self.view addSubview:imageview];
}

可以添加文本,checkBox,选择框等等到PDFPage,其挂件的frame要基于Page的大小确定。
fieldName用于给挂件分组。清空事件可以用到
buttonWidgetStateString相当挂件的ID,用来区分是否多选或单选

/**
 创建文本输入框

 @param bounds <#bounds description#>
 @param fieldName <#fieldName description#>
 @return <#return value description#>
 */
- (PDFAnnotation *)textWidgetWithBounds:(CGRect)bounds filedName:(NSString *)fieldName {
    PDFAnnotation *textWidget = [[PDFAnnotation alloc] initWithBounds:bounds forType:PDFAnnotationSubtypeText withProperties:nil];
    textWidget.fieldName = fieldName;
    textWidget.font = [UIFont systemFontOfSize:18];
    return textWidget;
}

 textWidget.maximumLength = 10; //限制文本长度
 textWidget.hasComb = YES; //等分间距


/**
 创建选择按钮

 @param fieldName <#fieldName description#>
 @param state <#state description#>
 @param bounds <#bounds description#>
 @return <#return value description#>
 */
- (PDFAnnotation *)radiobuttonWithFieldName:(NSString *)fieldName state:(NSString *)state bounds:(CGRect)bounds {
    PDFAnnotation * button = [[PDFAnnotation alloc] initWithBounds:bounds forType:PDFAnnotationWidgetSubtypeButton withProperties:nil];
    button.widgetFieldType = PDFAnnotationWidgetSubtypeButton;
    button.widgetControlType = kPDFWidgetRadioButtonControl;
    button.buttonWidgetStateString = state;
    return button;
}

创建一个挂件类型为 kPDFWidgetPushButtonControl 的按钮,PDFActionResetForm类配置清除属性。clearButton.action = resetFormAction;最后赋值给按钮

- (void)clearAction {
    CGRect clearButtonBounds = CGRectMake(0, 0, 1, 1);
    PDFAnnotation *clearButton = [[PDFAnnotation alloc] initWithBounds:clearButtonBounds forType:PDFAnnotationSubtypeWidget withProperties:nil];
    clearButton.widgetFieldType = PDFAnnotationWidgetSubtypeButton;
    clearButton.widgetControlType = kPDFWidgetPushButtonControl;
    clearButton.caption = @"Clear";
    clearButton.fieldName =  @"Clear";
    
    PDFPage *page = [self.document pageAtIndex:0];
    
    [page addAnnotation:clearButton];
    
    PDFActionResetForm *resetFormAction = [[PDFActionResetForm alloc] init];
    resetFormAction.fields = @[@"A",@"B",@"C"];
    resetFormAction.fieldsIncludedAreCleared = NO; //FieldName为 @[@"A",@"B",@"C"] 的挂件,不清楚记录
    clearButton.action = resetFormAction;
}
- (void)saveDocument {
    PDFPage *page = [self.document pageAtIndex:0];
    if (page == nil) {
        return;
    }
    
    NSString *pdfName = nil;
    for (PDFAnnotation *annotation in page.annotations) {
        if ([annotation.fieldName isEqualToString:@"xxx"]) {
            [page removeAnnotation:annotation]; //根据需求决定是否移除某些挂件
        }
        else if([annotation.fieldName isEqualToString:@"name"]){
            pdfName = annotation.widgetStringValue; //取出用户添加的内容作为文件名
        }
    }
    if (pdfName) {
        pdfName = [pdfName stringByReplacingOccurrencesOfString:@" " withString:@"_"];
        pdfName = [NSString stringWithFormat:@"%@.pdf",pdfName];
       NSString* documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        NSString * filePath = [NSString stringWithFormat:@"%@%@",documentDir,pdfName];
        
        // 保存并设置密码
        [self.document writeToURL:[NSURL URLWithString:filePath] withOptions:@{PDFDocumentOwnerPasswordOption:@"mima"}];
    }
}
    PDFPage *page = [self.document pageAtIndex:0];
    if (page) {
        if (self.document.isEncrypted || self.document.isLocked) {
            for (PDFAnnotation *anntation in page.annotations) {
                anntation.readOnly = YES; //设置后文件输入框还是可以编辑不知是不是bug。
            }
        }
    }

1.成为PDFDocument代理 有坑,必须设置代理之后再将document赋值给PDFView,否则不会调用
2.实现代理 - (Class)classForPage
3.实现自定类PDFPage,实现- (void)drawWithBox:(PDFDisplayBox)box toContext:(CGContextRef)context 方法

  document.delegate = self;
  self.pdfView.document = document; //正确
       /*
         self.pdfView.document = document;
         document.delegate = self;   错误 代理不会调用
       */

#pragma  mark - PDFDocumentDelegate

- (Class)classForPage {
    
    return WaterMark.class;
}

@implementation WaterMark
- (void)drawWithBox:(PDFDisplayBox)box toContext:(CGContextRef)context {
    [super drawWithBox:box toContext:context];
    UIGraphicsPushContext(context);
    CGContextSaveGState(context);

    CGRect pageBounds = [self boundsForBox:box];
    CGContextTranslateCTM(context, 0, pageBounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextRotateCTM(context, M_PI_4);
    
    NSString *str = @"水印 水印 水印";
    NSDictionary  *attributes = @{
                      NSForegroundColorAttributeName: [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.5],
                      NSFontAttributeName: [UIFont systemFontOfSize:64]
                      };
    
    [str drawAtPoint:CGPointMake(250, 40) withAttributes:attributes];
    
    CGContextRestoreGState(context);
    UIGraphicsPopContext();

}
@end

图片.png
上一篇 下一篇

猜你喜欢

热点阅读