Files
Pariece McKinney c71d1a56dd Public release 3.0.1
2024-05-08 14:56:11 -04:00

861 lines
41 KiB
Objective-C

/*
Copyright (c) 2018, Apple Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of the copyright holder(s) nor the names of any contributors
may be used to endorse or promote products derived from this software without
specific prior written permission. No license is granted to the trademarks of
the copyright holders even if such marks are included in this software.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@import PDFKit;
#import "ORKPDFViewerStepView_Internal.h"
#import "ORKFreehandDrawingView.h"
#import "ORKHelpers_Internal.h"
#import "ORKBorderedButton.h"
#import "ORKSkin.h"
const CGFloat PDFSearchBarHeight = 40.0;
const CGFloat PDFActionViewHeight = 25.0;
const CGFloat PDFActionItemPadding = 1.0;
const CGFloat PDFThumbnailViewWidth = 60.0;
const CGFloat PDFActionsViewLeftRightPadding = 20.0;
const CGFloat PDFParentStackViewSpacing = 10.0;
const CGFloat PDFInactiveButtonAlpha = 0.5;
const CGFloat PDFhideViewAnimationDuration = 0.5;
NSString * const ORKPDFViewerStepShowPDFThumbnailActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_showPDF_thumbnailActionButton";
NSString * const ORKPDFViewerStepHidePDFThumbnailActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_hidePDF_thumbnailActionButton";
NSString * const ORKPDFViewerStepAnnotationActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_annotationActionButton";
NSString * const ORKPDFViewerStepShowSearchActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_showSearchActionButton";
NSString * const ORKPDFViewerStepHideSearchActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_hideSearchActionButton";
NSString * const ORKPDFViewerStepShareActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_shareActionButton";
NSString * const ORKPDFViewerActionViewExitButtonAccessibilityIdentifier = @"ORKPDFViewerActionView_exitButton";
NSString * const ORKPDFViewerActionViewApplyButtonAccessibilityIdentifier = @"ORKPDFViewerActionView_applyButton";
NSString * const ORKPDFViewerActionViewClearButtonAccessibilityIdentifier = @"ORKPDFViewerActionView_clearButton";
@interface ORKPDFViewerActionsView: UIView
@property (nonatomic, nonnull) UIView *thumbnailActionView;
@property (nonatomic, nonnull) UIView *annotationActionView;
@property (nonatomic, nonnull) UIView *searchActionView;
@property (nonatomic, nonnull) UIView *shareActionView;
@property (nonatomic, nonnull) UIView *clearButtonView;
@property (nonatomic, nonnull) UIView *applyButtonView;
@property (nonatomic, nonnull) UIView *exitButtonView;
@property (nonatomic, nonnull) UIStackView *stackView;
@property (nonatomic, nonnull) UIButton *thumbnailActionButton;
@property (nonatomic, nonnull) UIButton *annotationActionButton;
@property (nonatomic, nonnull) UIButton *searchActionButton;
@property (nonatomic, nonnull) UIButton *shareActionButton;
@property (nonatomic, nonnull) ORKBorderedButton *clearAnnotationsButton;
@property (nonatomic, nonnull) ORKBorderedButton *applyAnnotationsButton;
@property (nonatomic, nonnull) UIButton *exitAnnotationsButton;
@end
@implementation ORKPDFViewerActionsView
- (instancetype)init
{
self = [super init];
if (self) {
}
[self setupStackView];
[self setupConstraints];
return self;
}
- (void)setupStackView {
if (!_stackView) {
_stackView = [[UIStackView alloc] init];
}
_stackView.translatesAutoresizingMaskIntoConstraints = NO;
_stackView.spacing = 0.0;
_stackView.layoutMargins = UIEdgeInsetsMake(0.0, PDFActionsViewLeftRightPadding, 0.0, PDFActionsViewLeftRightPadding);
[_stackView setLayoutMarginsRelativeArrangement:YES];
_stackView.axis = UILayoutConstraintAxisHorizontal;
_stackView.distribution = UIStackViewDistributionFillEqually;
[self setupThumbnailAction];
[self setupAnnotationAction];
[self setupSearchAction];
[self setupShareAction];
[self setupClearAnnotationsButton];
[self setupApplyAnnotationsButton];
[self setupExitAnnotationsButton];
[self addSubview:_stackView];
}
- (void)setupThumbnailAction {
if (!_thumbnailActionButton) {
_thumbnailActionButton = [UIButton buttonWithType:UIButtonTypeCustom];
}
[_thumbnailActionButton setImage:[[UIImage imageNamed:@"pdfThumbnail" inBundle:ORKBundle() compatibleWithTraitCollection:nil] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
_thumbnailActionView = [UIView new];
_thumbnailActionView.translatesAutoresizingMaskIntoConstraints = NO;
_thumbnailActionButton.translatesAutoresizingMaskIntoConstraints = NO;
[_thumbnailActionView addSubview:_thumbnailActionButton];
[_stackView insertArrangedSubview:_thumbnailActionView atIndex:0];
[self activateConstraintsForButton:_thumbnailActionButton withView:_thumbnailActionView];
}
- (void)setupAnnotationAction {
if (!_annotationActionButton) {
_annotationActionButton = [UIButton buttonWithType:UIButtonTypeCustom];
}
[_annotationActionButton setImage:[[UIImage imageNamed:@"annotation" inBundle:ORKBundle() compatibleWithTraitCollection:nil] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
_annotationActionView = [UIView new];
_annotationActionView.translatesAutoresizingMaskIntoConstraints = NO;
_annotationActionButton.translatesAutoresizingMaskIntoConstraints = NO;
[_annotationActionView addSubview:_annotationActionButton];
[_stackView addArrangedSubview:_annotationActionView];
[self activateConstraintsForButton:_annotationActionButton withView:_annotationActionView];
}
- (void)setupSearchAction {
if (!_searchActionButton) {
_searchActionButton = [UIButton buttonWithType:UIButtonTypeCustom];
}
[_searchActionButton setImage:[[UIImage imageNamed:@"search" inBundle:ORKBundle() compatibleWithTraitCollection:nil] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
_searchActionView = [UIView new];
_searchActionView.translatesAutoresizingMaskIntoConstraints = NO;
_searchActionButton.translatesAutoresizingMaskIntoConstraints = NO;
[_searchActionView addSubview:_searchActionButton];
[_stackView addArrangedSubview:_searchActionView];
[self activateConstraintsForButton:_searchActionButton withView:_searchActionView];
}
- (void)setupShareAction {
if (!_shareActionButton) {
_shareActionButton = [UIButton buttonWithType:UIButtonTypeCustom];
}
[_shareActionButton setImage:[[UIImage imageNamed:@"share" inBundle:ORKBundle() compatibleWithTraitCollection:nil] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
_shareActionView = [UIView new];
_shareActionView.translatesAutoresizingMaskIntoConstraints = NO;
_shareActionButton.translatesAutoresizingMaskIntoConstraints = NO;
[_shareActionView addSubview:_shareActionButton];
[_stackView addArrangedSubview:_shareActionView];
[self activateConstraintsForButton:_shareActionButton withView:_shareActionView];
}
- (void)setupClearAnnotationsButton {
if (!_clearAnnotationsButton) {
_clearAnnotationsButton = [ORKBorderedButton new];
}
_clearAnnotationsButton.contentEdgeInsets = (UIEdgeInsets){.left = 6, .right = 6};
_clearAnnotationsButton.translatesAutoresizingMaskIntoConstraints = NO;
_clearButtonView = [UIView new];
_clearButtonView.translatesAutoresizingMaskIntoConstraints = NO;
_clearButtonView.accessibilityIdentifier = ORKPDFViewerActionViewClearButtonAccessibilityIdentifier;
[_clearAnnotationsButton setTitle:ORKLocalizedString(@"BUTTON_CLEAR", nil) forState:UIControlStateNormal];
[_clearButtonView addSubview:_clearAnnotationsButton];
[_stackView addArrangedSubview:_clearButtonView];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint constraintWithItem:_clearAnnotationsButton
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_clearButtonView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:_clearAnnotationsButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_clearButtonView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:_clearAnnotationsButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_clearButtonView
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0.0]
]];
}
- (void)setupApplyAnnotationsButton {
if (!_applyAnnotationsButton) {
_applyAnnotationsButton = [ORKBorderedButton new];
}
_applyAnnotationsButton.contentEdgeInsets = (UIEdgeInsets){.left = 6, .right = 6};
_applyAnnotationsButton.translatesAutoresizingMaskIntoConstraints = NO;
_applyButtonView = [UIView new];
_applyButtonView.translatesAutoresizingMaskIntoConstraints = NO;
_applyButtonView.accessibilityIdentifier = ORKPDFViewerActionViewApplyButtonAccessibilityIdentifier;
[_applyAnnotationsButton setTitle:ORKLocalizedString(@"BUTTON_APPLY", nil) forState:UIControlStateNormal];
[_applyButtonView addSubview:_applyAnnotationsButton];
[_stackView addArrangedSubview:_applyButtonView];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint constraintWithItem:_applyAnnotationsButton
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_applyButtonView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:_applyAnnotationsButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_applyButtonView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:_applyAnnotationsButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_applyButtonView
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0.0]
]];}
- (void)setupExitAnnotationsButton {
if (!_exitAnnotationsButton) {
_exitAnnotationsButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
}
[_exitAnnotationsButton setTitle:@"X" forState:UIControlStateNormal];
[_exitAnnotationsButton.titleLabel setAdjustsFontSizeToFitWidth:YES];
[_exitAnnotationsButton.titleLabel setFont:[UIFont boldSystemFontOfSize:[UIFont systemFontSize]]];
_exitAnnotationsButton.translatesAutoresizingMaskIntoConstraints = NO;
_exitButtonView = [UIView new];
_exitButtonView.translatesAutoresizingMaskIntoConstraints = NO;
_exitButtonView.accessibilityIdentifier = ORKPDFViewerActionViewExitButtonAccessibilityIdentifier;
[_exitButtonView addSubview:_exitAnnotationsButton];
[_stackView addArrangedSubview:_exitButtonView];
[self activateConstraintsForButton:_exitAnnotationsButton withView:_exitButtonView];
[self setExitAnnotationsButtonStyle];
}
- (void)activateConstraintsForButton:(UIButton *)button withView:(UIView *)view {
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:PDFActionViewHeight],
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:PDFActionViewHeight],
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]]];
}
- (void)setExitAnnotationsButtonStyle {
[_exitAnnotationsButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_exitAnnotationsButton setBackgroundColor:[[self tintColor] colorWithAlphaComponent:PDFInactiveButtonAlpha]];
[_exitAnnotationsButton.layer setCornerRadius:PDFActionViewHeight/2.0];
}
- (void)setupConstraints {
NSMutableArray *constraints = [NSMutableArray new];
NSDictionary *views = NSDictionaryOfVariableBindings(_stackView);
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_stackView]|"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_stackView]|"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[NSLayoutConstraint activateConstraints:constraints];
}
@end
@interface ORKPDFViewerStepView () <UISearchBarDelegate, PDFDocumentDelegate, ORKFreehandDrawingViewDelegate>
@end
@implementation ORKPDFViewerStepView {
UIStackView *_parentStackView, *_pdfStackView;
UISearchBar *_searchBar;
ORKPDFViewerActionsView *_pdfActionsView;
PDFView *_pdfView;
PDFThumbnailView *_pdfThumbnailView;
ORKFreehandDrawingView *_freehandDrawingView;
BOOL _isFreehandDrawingActive;
BOOL _isShareActive;
BOOL _annotationsAdded;
UIView *_keyboardUnderlapView;
}
- (instancetype)init {
self = [super init];
if (self) {
[self setupParentStackView];
[self setupSearchBar];
[self setupPDFActionsView];
[self setupPDFStackView];
[self setupKeyboardUnderlapView];
[self setupConstraints];
}
return self;
}
- (void)setupParentStackView {
if (!_parentStackView) {
_parentStackView = [[UIStackView alloc] init];
}
_parentStackView.translatesAutoresizingMaskIntoConstraints = NO;
_parentStackView.spacing = PDFParentStackViewSpacing;
_parentStackView.axis = UILayoutConstraintAxisVertical;
_parentStackView.distribution = UIStackViewDistributionFill;
[self addSubview:_parentStackView];
}
- (void)setupSearchBar {
if (!_searchBar) {
_searchBar = [[UISearchBar alloc] init];
}
[NSLayoutConstraint constraintWithItem:_searchBar
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:PDFSearchBarHeight].active = YES;
_searchBar.hidden = YES;
_searchBar.delegate = self;
_searchBar.barTintColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3];
_searchBar.translatesAutoresizingMaskIntoConstraints = NO;
[_parentStackView insertArrangedSubview:_searchBar atIndex:0];
}
- (void)setupPDFActionsView {
if (!_pdfActionsView) {
_pdfActionsView = [ORKPDFViewerActionsView new];
}
[NSLayoutConstraint constraintWithItem:_pdfActionsView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:PDFActionViewHeight].active = YES;
[self setupClearApplyExitButtons];
[_pdfActionsView.thumbnailActionButton addTarget:self action:@selector(thumbnailButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_pdfActionsView.annotationActionButton addTarget:self action:@selector(annotationButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_pdfActionsView.searchActionButton addTarget:self action:@selector(searchButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_pdfActionsView.shareActionButton addTarget:self action:@selector(shareButtonAction) forControlEvents:UIControlEventTouchUpInside];
_pdfActionsView.translatesAutoresizingMaskIntoConstraints = NO;
[_parentStackView addArrangedSubview:_pdfActionsView];
[self updateActionButtonAccessibilityLabels];
}
- (void)setupPDFStackView {
if (!_pdfStackView) {
[self setupPDFView];
_pdfStackView = [[UIStackView alloc] initWithArrangedSubviews:@[_pdfThumbnailView, _pdfView]];
}
_pdfStackView.translatesAutoresizingMaskIntoConstraints = NO;
_pdfStackView.spacing = 10.0;
_pdfStackView.axis = UILayoutConstraintAxisHorizontal;
_pdfStackView.distribution = UIStackViewDistributionFill;
[_parentStackView addArrangedSubview:_pdfStackView];
}
- (void)setupPDFView {
if (!_pdfView) {
_pdfView = [PDFView new];
}
PDFDocument *document;
if (_pdfURL) {
document = [[PDFDocument alloc] initWithURL:_pdfURL];
_pdfView.document = document;
_pdfView.document.delegate = self;
}
if (document) {
[self setEnableAllButtons:!document.isLocked];
}
else {
[self setEnableAllButtons:document];
}
_pdfView.autoScales = YES;
_pdfView.displayMode = kPDFDisplaySinglePageContinuous;
_pdfView.translatesAutoresizingMaskIntoConstraints = NO;
_pdfThumbnailView = [PDFThumbnailView new];
_pdfThumbnailView.translatesAutoresizingMaskIntoConstraints = NO;
_pdfThumbnailView.thumbnailSize = CGSizeMake(40, 40);
[NSLayoutConstraint constraintWithItem:_pdfThumbnailView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:PDFThumbnailViewWidth].active = YES;
_pdfThumbnailView.layoutMode = PDFThumbnailLayoutModeVertical;
_pdfThumbnailView.PDFView = _pdfView;
_pdfThumbnailView.hidden = YES;
[self updateActionButtonsAppearance];
}
- (void)setupClearApplyExitButtons {
[_pdfActionsView.clearButtonView setHidden:YES];
[_pdfActionsView.applyButtonView setHidden:YES];
[_pdfActionsView.exitButtonView setHidden:YES];
[self updateClearApplyAnnotationButtons];
[_pdfActionsView.clearAnnotationsButton addTarget:self action:@selector(clearButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_pdfActionsView.applyAnnotationsButton addTarget:self action:@selector(applybuttonAction) forControlEvents:UIControlEventTouchUpInside];
[_pdfActionsView.exitAnnotationsButton addTarget:self action:@selector(exitButtonAction) forControlEvents:UIControlEventTouchUpInside];
}
- (void)updateClearApplyAnnotationButtons {
[_pdfActionsView.clearAnnotationsButton setEnabled:_freehandDrawingView.freehandDrawingExists];
[_pdfActionsView.applyAnnotationsButton setEnabled:_freehandDrawingView.freehandDrawingExists];
}
- (void)thumbnailButtonAction {
[self animateViews:@[_pdfThumbnailView] setHidden:!_pdfThumbnailView.isHidden];
[self updateActionButtonsAppearance];
[_pdfView setAutoScales:YES];
}
- (void)annotationButtonAction {
[self setPDFViewDisplayModeSinglePage:_isFreehandDrawingActive];
if (!_isFreehandDrawingActive && !_freehandDrawingView) {
[self addFreehandDrawingView];
}
[self setIsScibbleActive:YES];
[self updateActionButtonsAppearance];
}
- (void)addAnnotations: (PDFAnnotation *)annotations {
[_pdfView.currentPage addAnnotation:annotations];
}
- (void)setPDFViewDisplayModeSinglePage:(BOOL) isContinuous {
PDFPage *currentPage = _pdfView.currentPage;
[_pdfView setScaleFactor:[_pdfView minScaleFactor]];
[_pdfView setDisplayMode:isContinuous ? kPDFDisplaySinglePageContinuous : kPDFDisplaySinglePage];
[_pdfView setScaleFactor:[_pdfView scaleFactorForSizeToFit]];
[_pdfView goToPage:currentPage];
}
- (void)searchButtonAction {
[UIView animateWithDuration:0.5 animations:^{
if (!_searchBar.isHidden) {
[self searchBarDismissKeyboard];
}
_searchBar.hidden = !_searchBar.isHidden;
}];
[self updateActionButtonsAppearance];
}
- (void)setEnableAllButtons:(BOOL)enable {
[_pdfActionsView.thumbnailActionButton setEnabled:enable];
[_pdfActionsView.annotationActionButton setEnabled:enable];
[_pdfActionsView.searchActionButton setEnabled:enable];
[_pdfActionsView.shareActionButton setEnabled:enable];
}
- (void)updateActionButtonsAppearance {
_pdfActionsView.thumbnailActionButton.alpha = _pdfThumbnailView.isHidden ? PDFInactiveButtonAlpha : 1.0;
_pdfActionsView.annotationActionButton.alpha = !_isFreehandDrawingActive ? PDFInactiveButtonAlpha : 1.0;
_pdfActionsView.searchActionButton.alpha = _searchBar.isHidden ? PDFInactiveButtonAlpha : 1.0;
_pdfActionsView.shareActionButton.alpha = PDFInactiveButtonAlpha;
[self updateActionButtonAccessibilityLabels];
}
- (void)updateActionButtonAccessibilityLabels {
_pdfActionsView.thumbnailActionButton.accessibilityLabel = _pdfThumbnailView.isHidden ?ORKLocalizedString(@"AX_BUTTON_SHOW_PDF_THUMBNAIL" , nil) : ORKLocalizedString(@"AX_BUTTON_HIDE_PDF_THUMBNAIL", nil);
_pdfActionsView.annotationActionButton.accessibilityLabel = ORKLocalizedString(@"AX_BUTTON_ANNOTATE" , nil);
_pdfActionsView.searchActionButton.accessibilityLabel = _searchBar.isHidden ? ORKLocalizedString(@"AX_BUTTON_SHOW_SEARCH", nil) : ORKLocalizedString(@"AX_BUTTON_HIDE_SEARCH", nil);
_pdfActionsView.shareActionButton.accessibilityLabel = ORKLocalizedString(@"AX_BUTTON_SHARE", nil);
_pdfActionsView.thumbnailActionButton.accessibilityIdentifier = _pdfThumbnailView.isHidden ?ORKPDFViewerStepShowPDFThumbnailActionButtonAccessibilityIdentifier : ORKPDFViewerStepHidePDFThumbnailActionButtonAccessibilityIdentifier;
_pdfActionsView.annotationActionButton.accessibilityIdentifier = ORKPDFViewerStepAnnotationActionButtonAccessibilityIdentifier;
_pdfActionsView.searchActionButton.accessibilityIdentifier = _searchBar.isHidden ? ORKPDFViewerStepShowSearchActionButtonAccessibilityIdentifier : ORKPDFViewerStepHideSearchActionButtonAccessibilityIdentifier;
_pdfActionsView.shareActionButton.accessibilityIdentifier = ORKPDFViewerStepShareActionButtonAccessibilityIdentifier;
}
- (void)shareButtonAction {
if (_isShareActive) {
}
else {
if (self.delegate && [self.delegate respondsToSelector:@selector(didSelectShareButton:)]) {
[self.delegate didSelectShareButton:_pdfActionsView.shareActionButton];
}
}
_isShareActive = !_isShareActive;
[self updateActionButtonsAppearance];
}
- (void)setPdfURL:(NSURL *)pdfURL {
if (_pdfURL != pdfURL) {
_pdfURL = pdfURL;
_pdfView.document = nil;
PDFDocument *document;
if (pdfURL) {
document = [[PDFDocument alloc] initWithURL:pdfURL];
_pdfView.document = document;
_pdfView.document.delegate = self;
}
if (document) {
[self setEnableAllButtons:!document.isLocked];
_annotationsAdded = NO;
}
else {
[self setEnableAllButtons:document];
}
}
}
- (void)addFreehandDrawingView {
if (!_freehandDrawingView) {
_freehandDrawingView = [[ORKFreehandDrawingView alloc] initWithPDFView:_pdfView];
_freehandDrawingView.translatesAutoresizingMaskIntoConstraints = NO;
_freehandDrawingView.backgroundColor = [UIColor clearColor];
_freehandDrawingView.opaque = NO;
_freehandDrawingView.delegate = self;
[self addSubview:_freehandDrawingView];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint constraintWithItem:_freehandDrawingView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:_pdfView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:_freehandDrawingView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:_pdfView
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:_freehandDrawingView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:_pdfView
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:_freehandDrawingView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:_pdfView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0]
]];
}
}
- (void)setupKeyboardUnderlapView {
if (!_keyboardUnderlapView) {
_keyboardUnderlapView = [UIView new];
}
_keyboardUnderlapView.translatesAutoresizingMaskIntoConstraints = NO;
_keyboardUnderlapView.hidden = YES;
[_keyboardUnderlapView setBackgroundColor:[UIColor clearColor]];
[_parentStackView addArrangedSubview:_keyboardUnderlapView];
}
- (void)setIsScibbleActive:(BOOL)isActive {
_isFreehandDrawingActive = isActive;
if (isActive) {
[self searchBarDismissKeyboard];
[_pdfActionsView.thumbnailActionButton setHidden:YES];
[_pdfActionsView.annotationActionButton setHidden:YES];
[_pdfActionsView.searchActionButton setHidden:YES];
[_pdfActionsView.shareActionButton setHidden:YES];
[_pdfActionsView.clearAnnotationsButton setHidden:NO];
[_pdfActionsView.applyAnnotationsButton setHidden:NO];
[_pdfActionsView.exitAnnotationsButton setHidden:NO];
[self animateViews:@[
_pdfThumbnailView,
_pdfActionsView.thumbnailActionView,
_pdfActionsView.annotationActionView,
_searchBar,
_pdfActionsView.searchActionView,
_pdfActionsView.shareActionView
]
setHidden:YES];
[self animateViews:@[
_pdfActionsView.clearButtonView,
_pdfActionsView.applyButtonView,
_pdfActionsView.exitButtonView
] setHidden:NO];
}
else {
NSMutableArray *allowedViews = [[NSMutableArray alloc] init];
[_pdfActionsView.thumbnailActionButton setHidden:NO];
[_pdfActionsView.annotationActionButton setHidden:NO];
[_pdfActionsView.clearAnnotationsButton setHidden:YES];
[_pdfActionsView.applyAnnotationsButton setHidden:YES];
[_pdfActionsView.exitAnnotationsButton setHidden:YES];
[allowedViews addObjectsFromArray:@[_pdfActionsView.thumbnailActionView,
_pdfActionsView.annotationActionView]];
if (!_hideSearchButton) {
[_pdfActionsView.searchActionButton setHidden:NO];
[allowedViews addObject:_pdfActionsView.searchActionView];
}
if (!_hideShareButton) {
[_pdfActionsView.shareActionButton setHidden:NO];
[allowedViews addObject:_pdfActionsView.shareActionView];
}
[self animateViews:allowedViews setHidden:NO];
[self animateViews:@[_pdfActionsView.clearButtonView,
_pdfActionsView.applyButtonView,
_pdfActionsView.exitButtonView]
setHidden:YES];
}
[self updateActionButtonsAppearance];
}
- (void)clearButtonAction {
if (_freehandDrawingView.freehandDrawingPath && _freehandDrawingView.freehandDrawingExists) {
[_freehandDrawingView clear];
}
[self updateClearApplyAnnotationButtons];
}
- (void)applybuttonAction {
if (_freehandDrawingView.freehandDrawingPath && _freehandDrawingView.freehandDrawingExists) {
CGRect annotationRect = _pdfView.documentView.bounds;
PDFAnnotation *annotation = [[PDFAnnotation alloc] initWithBounds:annotationRect forType:PDFAnnotationSubtypeInk withProperties:nil];
annotation.border.lineWidth = 2.0;
for (UIBezierPath *path in _freehandDrawingView.freehandDrawingPath) {
[annotation addBezierPath:path];
}
[_pdfView.currentPage addAnnotation:annotation];
[_freehandDrawingView clear];
_annotationsAdded = YES;
}
[self updateClearApplyAnnotationButtons];
}
- (void)exitButtonAction {
[self setPDFViewDisplayModeSinglePage:_isFreehandDrawingActive];
if (_isFreehandDrawingActive && _freehandDrawingView) {
[_freehandDrawingView removeFromSuperview];
_freehandDrawingView = nil;
[self setIsScibbleActive:NO];
}
}
- (void)setHideThumbnailButton:(BOOL)hideThumbnailButton {
if (hideThumbnailButton) {
[_pdfActionsView.thumbnailActionView setHidden:YES];
[_pdfThumbnailView setHidden:YES];
}
}
- (void)setHideAnnotationButton:(BOOL)hideAnnotationButton {
if (hideAnnotationButton) {
[_pdfActionsView.annotationActionView setHidden:YES];
[_pdfActionsView.clearButtonView setHidden:YES];
[_pdfActionsView.applyButtonView setHidden:YES];
[_pdfActionsView.exitButtonView setHidden:YES];
}
}
- (void)setHideSearchButton:(BOOL)hideSearchButton {
if (hideSearchButton) {
[_pdfActionsView.searchActionView setHidden:YES];
[_searchBar setHidden:YES];
}
}
- (void)setHideShareButton:(BOOL)hideShareButton {
[_pdfActionsView.shareActionView setHidden:hideShareButton];
}
- (void)setupConstraints {
NSMutableArray *constraints = [NSMutableArray new];
NSDictionary *views = NSDictionaryOfVariableBindings(_parentStackView);
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_parentStackView]|"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_parentStackView]|"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[NSLayoutConstraint activateConstraints:constraints];
}
- (void)searchBarDismissKeyboard {
[_searchBar resignFirstResponder];
if (_keyboardUnderlapView) {
_keyboardUnderlapView.hidden = YES;
}
}
- (BOOL)pdfModified {
return _annotationsAdded;
}
- (void)animateViews:(NSArray<UIView *> *)views setHidden:(BOOL)hidden {
[UIView animateWithDuration:PDFhideViewAnimationDuration animations:^{
for (UIView *view in views) {
[view setHidden:hidden];
}
}];
}
- (PDFDocument *)getDocument {
return _pdfView.document;
}
#pragma mark UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
[_pdfView.document beginFindString:searchText withOptions:NSCaseInsensitiveSearch];
}
- (void)didMatchString:(PDFSelection *)instance {
instance.color = [UIColor yellowColor];
[_pdfView setCurrentSelection:instance animate:YES];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[_pdfView.document beginFindString:searchBar.text withOptions:NSCaseInsensitiveSearch];
[self searchBarDismissKeyboard];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
if (_keyboardUnderlapView) {
_keyboardUnderlapView.hidden = YES;
}
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWillAppear:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;
CGSize keyboardSize = ((NSValue *)userInfo[UIKeyboardFrameEndUserInfoKey]).CGRectValue.size;
// Offset with assumed view controller's navigation container's height.
keyboardSize.height = keyboardSize.height - 200.0;
if (_keyboardUnderlapView && _keyboardUnderlapView.isHidden) {
[_keyboardUnderlapView removeFromSuperview];
[NSLayoutConstraint constraintWithItem:_keyboardUnderlapView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:keyboardSize.height].active = YES;
_keyboardUnderlapView.hidden = NO;
[_parentStackView insertArrangedSubview:_keyboardUnderlapView atIndex:[[_parentStackView subviews] count]];
}
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)updateShareButton {
_isShareActive = NO;
[self updateActionButtonsAppearance];
}
#pragma mark ORKFreehandDrawingViewDelegate
- (void)freehandDrawingViewDidEditImage:(ORKFreehandDrawingView *)freehandDrawingView {
[self updateClearApplyAnnotationButtons];
}
#pragma mark PDFDocumentDelegate
- (void)documentDidUnlock:(NSNotification *)notification {
[self setEnableAllButtons:YES];
}
@end