Separate Photo Library and Camera Actions

How can I add two separate buttons for adding images annotations from the Photo Library and Camera?

The most flexible way to achieve this would be to present UIImagePickerController or PHPickerViewController from your own code and then add a StampAnnotation with the image you get from the picker.

Alternatively, you can achieve this with PSPDFKit with subclasses of PSPDFKit’s ImagePickerController that only allow one source type. For example:

Copy
1
2
3
4
5
class OnlyPhotoLibraryPickerController: ImagePickerController {
    override class func availableImagePickerSourceTypes() -> [NSNumber] {
        return [NSNumber(value: UIImagePickerController.SourceType.photoLibrary.rawValue)]
    }
}

In a button action method in a subclass of PDFViewController, register the subclass just before showing the image picker:

Copy
1
2
3
4
5
6
@objc func togglePhotoLibrary(_ sender: UIBarButtonItem) {
    self.updateConfiguration {
        $0.overrideClass(ImagePickerController.self, with: OnlyPhotoLibraryPickerController.self)
    }
    self.annotationStateManager.toggleImagePickerController(sender, presentationOptions: nil)
}

Here’s a complete subclass of PDFViewController adding two separate buttons: one to import images from the Photo Library and one to import from the Camera:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class SeparateImagePickersPDFViewController: PDFViewController {
    override func commonInit(with document: Document?, configuration: PDFConfiguration) {
        super.commonInit(with: document, configuration: configuration)

        var leftBarButtonItems = navigationItem.leftBarButtonItems(for: .document) ?? []
        leftBarButtonItems += [
            UIBarButtonItem(title: "Library", style: .plain, target: self, action: #selector(togglePhotoLibrary)),
            UIBarButtonItem(title: "Camera", style: .plain, target: self, action: #selector(toggleCamera)),
        ]
        navigationItem.setLeftBarButtonItems(leftBarButtonItems, for: .document, animated: false)
        navigationItem.leftItemsSupplementBackButton = true
    }

    @objc private func togglePhotoLibrary(_ sender: UIBarButtonItem) {
        updateConfiguration {
            $0.overrideClass(ImagePickerController.self, with: OnlyPhotoLibraryPickerController.self)
        }
        annotationStateManager.toggleImagePickerController(sender, presentationOptions: nil)
    }

    @objc private func toggleCamera(_ sender: UIBarButtonItem) {
        updateConfiguration {
            $0.overrideClass(ImagePickerController.self, with: OnlyCameraPickerController.self)
        }
        annotationStateManager.toggleImagePickerController(sender, presentationOptions: nil)
    }
}

private class OnlyPhotoLibraryPickerController: ImagePickerController {
    override class func availableImagePickerSourceTypes() -> [NSNumber] {
        return [NSNumber(value: UIImagePickerController.SourceType.photoLibrary.rawValue)]
    }
}

private class OnlyCameraPickerController: ImagePickerController {
    override class func availableImagePickerSourceTypes() -> [NSNumber] {
        return [NSNumber(value: UIImagePickerController.SourceType.camera.rawValue)]
    }
}
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@interface SeparateImagePickersPDFViewController : PSPDFViewController
@end
@interface OnlyPhotoLibraryPickerController : PSPDFImagePickerController
@end
@interface OnlyCameraPickerController : PSPDFImagePickerController
@end

@implementation SeparateImagePickersPDFViewController

- (void)commonInitWithDocument:(PSPDFDocument *)document configuration:(PSPDFConfiguration *)configuration {
    [super commonInitWithDocument:document configuration:configuration];

    NSMutableArray<UIBarButtonItem *> *leftBarButtonItems = [NSMutableArray arrayWithArray:[self.navigationItem leftBarButtonItemsForViewMode:PSPDFViewModeDocument]];
    [leftBarButtonItems addObjectsFromArray:@[
        [[UIBarButtonItem alloc] initWithTitle:@"Library" style:UIBarButtonItemStylePlain target:self action:@selector(togglePhotoLibrary:)],
        [[UIBarButtonItem alloc] initWithTitle:@"Camera" style:UIBarButtonItemStylePlain target:self action:@selector(toggleCamera:)],
    ]];
    [self.navigationItem setLeftBarButtonItems:leftBarButtonItems forViewMode:PSPDFViewModeDocument animated:NO];
    self.navigationItem.leftItemsSupplementBackButton = YES;
}

- (void)togglePhotoLibrary:(UIBarButtonItem *)sender {
    [self updateConfigurationWithBuilder:^(PSPDFConfigurationBuilder *builder) {
        [builder overrideClass:PSPDFImagePickerController.class withClass:OnlyPhotoLibraryPickerController.class];
    }];
    [self.annotationStateManager toggleImagePickerController:sender presentationOptions:nil];
}

- (void)toggleCamera:(UIBarButtonItem *)sender {
    [self updateConfigurationWithBuilder:^(PSPDFConfigurationBuilder *builder) {
        [builder overrideClass:PSPDFImagePickerController.class withClass:OnlyCameraPickerController.class];
    }];
    [self.annotationStateManager toggleImagePickerController:sender presentationOptions:nil];
}

@end

@implementation OnlyPhotoLibraryPickerController

+ (NSArray<NSNumber *> *)availableImagePickerSourceTypes {
    return @[@(UIImagePickerControllerSourceTypePhotoLibrary)];
}

@end

@implementation OnlyCameraPickerController

+ (NSArray<NSNumber *> *)availableImagePickerSourceTypes {
    return @[@(UIImagePickerControllerSourceTypeCamera)];
}

@end