Skip to content

Commit 7289e06

Browse files
authored
Merge pull request #143 from PSPDFKit/rad/add-support-for-removing-annotations-ios
Add support for programmatically removing annotations on iOS
2 parents f35e03e + ce33d6c commit 7289e06

File tree

5 files changed

+142
-31
lines changed

5 files changed

+142
-31
lines changed

index.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class PSPDFKitView extends React.Component {
9797
[]
9898
);
9999
} else if (Platform.OS === "ios") {
100-
NativeModules.PSPDFKitViewManager.enterAnnotationCreationMode(
100+
return NativeModules.PSPDFKitViewManager.enterAnnotationCreationMode(
101101
findNodeHandle(this.refs.pdfView)
102102
);
103103
}
@@ -114,7 +114,7 @@ class PSPDFKitView extends React.Component {
114114
[]
115115
);
116116
} else if (Platform.OS === "ios") {
117-
NativeModules.PSPDFKitViewManager.exitCurrentlyActiveMode(
117+
return NativeModules.PSPDFKitViewManager.exitCurrentlyActiveMode(
118118
findNodeHandle(this.refs.pdfView)
119119
);
120120
}
@@ -131,7 +131,7 @@ class PSPDFKitView extends React.Component {
131131
[]
132132
);
133133
} else if (Platform.OS === "ios") {
134-
NativeModules.PSPDFKitViewManager.saveCurrentDocument(
134+
return NativeModules.PSPDFKitViewManager.saveCurrentDocument(
135135
findNodeHandle(this.refs.pdfView)
136136
);
137137
}
@@ -185,7 +185,28 @@ class PSPDFKitView extends React.Component {
185185
[annotation]
186186
);
187187
} else if (Platform.OS === "ios") {
188-
NativeModules.PSPDFKitViewManager.addAnnotation(
188+
return NativeModules.PSPDFKitViewManager.addAnnotation(
189+
annotation,
190+
findNodeHandle(this.refs.pdfView)
191+
);
192+
}
193+
};
194+
195+
/**
196+
* Removes an existing annotation from the current document.
197+
*
198+
* @param annotation InstantJson of the annotation to remove.
199+
*/
200+
removeAnnotation = function(annotation) {
201+
if (Platform.OS === "android") {
202+
// TODO: Uncomment once the Android implementaion is ready.
203+
// UIManager.dispatchViewManagerCommand(
204+
// findNodeHandle(this.refs.pdfView),
205+
// UIManager.RCTPSPDFKitView.Commands.removeAnnotation,
206+
// [annotation]
207+
// );
208+
} else if (Platform.OS === "ios") {
209+
return NativeModules.PSPDFKitViewManager.removeAnnotation(
189210
annotation,
190211
findNodeHandle(this.refs.pdfView)
191212
);
@@ -234,7 +255,7 @@ class PSPDFKitView extends React.Component {
234255
[annotations]
235256
);
236257
} else if (Platform.OS === "ios") {
237-
NativeModules.PSPDFKitViewManager.addAnnotations(
258+
return NativeModules.PSPDFKitViewManager.addAnnotations(
238259
annotations,
239260
findNodeHandle(this.refs.pdfView)
240261
);

ios/RCTPSPDFKit/RCTPSPDFKitView.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,18 @@
2929
@property (nonatomic, copy) RCTBubblingEventBlock onStateChanged;
3030

3131
/// Annotation Toolbar
32-
- (void)enterAnnotationCreationMode;
33-
- (void)exitCurrentlyActiveMode;
32+
- (BOOL)enterAnnotationCreationMode;
33+
- (BOOL)exitCurrentlyActiveMode;
3434

3535
/// Document
36-
- (void)saveCurrentDocument;
36+
- (BOOL)saveCurrentDocument;
3737

3838
/// Anotations
3939
- (NSDictionary<NSString *, NSArray<NSDictionary *> *> *)getAnnotations:(PSPDFPageIndex)pageIndex type:(PSPDFAnnotationType)type;
40-
- (void)addAnnotation:(NSString *)jsonAnnotation;
40+
- (BOOL)addAnnotation:(id)jsonAnnotation;
41+
- (BOOL)removeAnnotation:(id)jsonAnnotation;
4142
- (NSDictionary<NSString *, NSArray<NSDictionary *> *> *)getAllUnsavedAnnotations;
42-
- (void)addAnnotations:(NSString *)jsonAnnotations;
43+
- (BOOL)addAnnotations:(NSString *)jsonAnnotations;
4344

4445
/// Forms
4546
- (NSDictionary<NSString *, NSString *> *)getFormFieldValue:(NSString *)fullyQualifiedName;

ios/RCTPSPDFKit/RCTPSPDFKitView.m

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,18 @@ - (UIViewController *)pspdf_parentViewController {
105105
return nil;
106106
}
107107

108-
- (void)enterAnnotationCreationMode {
108+
- (BOOL)enterAnnotationCreationMode {
109109
[self.pdfController setViewMode:PSPDFViewModeDocument animated:YES];
110110
[self.pdfController.annotationToolbarController updateHostView:nil container:nil viewController:self.pdfController];
111-
[self.pdfController.annotationToolbarController showToolbarAnimated:YES];
111+
return [self.pdfController.annotationToolbarController showToolbarAnimated:YES];
112112
}
113113

114-
- (void)exitCurrentlyActiveMode {
115-
[self.pdfController.annotationToolbarController hideToolbarAnimated:YES];
114+
- (BOOL)exitCurrentlyActiveMode {
115+
return [self.pdfController.annotationToolbarController hideToolbarAnimated:YES];
116116
}
117117

118-
- (void)saveCurrentDocument {
119-
[self.pdfController.document saveWithOptions:nil error:NULL];
118+
- (BOOL)saveCurrentDocument {
119+
return [self.pdfController.document saveWithOptions:nil error:NULL];
120120
}
121121

122122
#pragma mark - PSPDFDocumentDelegate
@@ -178,15 +178,15 @@ - (void)flexibleToolbarContainerDidHide:(PSPDFFlexibleToolbarContainer *)contain
178178
return @{@"annotations" : annotationsJSON};
179179
}
180180

181-
- (void)addAnnotation:(id)jsonAnnotation {
181+
- (BOOL)addAnnotation:(id)jsonAnnotation {
182182
NSData *data;
183183
if ([jsonAnnotation isKindOfClass:NSString.class]) {
184184
data = [jsonAnnotation dataUsingEncoding:NSUTF8StringEncoding];
185185
} else if ([jsonAnnotation isKindOfClass:NSDictionary.class]) {
186186
data = [NSJSONSerialization dataWithJSONObject:jsonAnnotation options:0 error:nil];
187187
} else {
188188
NSLog(@"Invalid JSON Annotation.");
189-
return;
189+
return NO;
190190
}
191191

192192
PSPDFDocument *document = self.pdfController.document;
@@ -201,6 +201,40 @@ - (void)addAnnotation:(id)jsonAnnotation {
201201
if (!success) {
202202
NSLog(@"Failed to add annotation.");
203203
}
204+
205+
return success;
206+
}
207+
208+
- (BOOL)removeAnnotation:(id)jsonAnnotation {
209+
NSData *data;
210+
if ([jsonAnnotation isKindOfClass:NSString.class]) {
211+
data = [jsonAnnotation dataUsingEncoding:NSUTF8StringEncoding];
212+
} else if ([jsonAnnotation isKindOfClass:NSDictionary.class]) {
213+
data = [NSJSONSerialization dataWithJSONObject:jsonAnnotation options:0 error:nil];
214+
} else {
215+
NSLog(@"Invalid JSON Annotation.");
216+
return NO;
217+
}
218+
219+
PSPDFDocument *document = self.pdfController.document;
220+
PSPDFDocumentProvider *documentProvider = document.documentProviders.firstObject;
221+
222+
BOOL success = NO;
223+
if (data) {
224+
PSPDFAnnotation *annotationToRemove = [PSPDFAnnotation annotationFromInstantJSON:data documentProvider:documentProvider error:NULL];
225+
for (PSPDFAnnotation *annotation in [document annotationsForPageAtIndex:annotationToRemove.pageIndex type:annotationToRemove.type]) {
226+
// Remove the annotation if the name matches.
227+
if ([annotation.name isEqualToString:annotationToRemove.name]) {
228+
success = [document removeAnnotations:@[annotation] options:nil];
229+
break;
230+
}
231+
}
232+
}
233+
234+
if (!success) {
235+
NSLog(@"Failed to remove annotation.");
236+
}
237+
return success;
204238
}
205239

206240
- (NSDictionary<NSString *, NSArray<NSDictionary *> *> *)getAllUnsavedAnnotations {
@@ -210,15 +244,15 @@ - (void)addAnnotation:(id)jsonAnnotation {
210244
return annotationsJSON;
211245
}
212246

213-
- (void)addAnnotations:(id)jsonAnnotations {
247+
- (BOOL)addAnnotations:(id)jsonAnnotations {
214248
NSData *data;
215249
if ([jsonAnnotations isKindOfClass:NSString.class]) {
216250
data = [jsonAnnotations dataUsingEncoding:NSUTF8StringEncoding];
217251
} else if ([jsonAnnotations isKindOfClass:NSDictionary.class]) {
218-
data = [NSJSONSerialization dataWithJSONObject:jsonAnnotations options:0 error:nil];;
252+
data = [NSJSONSerialization dataWithJSONObject:jsonAnnotations options:0 error:nil];
219253
} else {
220254
NSLog(@"Invalid JSON Annotations.");
221-
return;
255+
return NO;
222256
}
223257

224258
PSPDFDataContainerProvider *dataContainerProvider = [[PSPDFDataContainerProvider alloc] initWithData:data];
@@ -228,6 +262,8 @@ - (void)addAnnotations:(id)jsonAnnotations {
228262
if (!success) {
229263
NSLog(@"Failed to add annotations.");
230264
}
265+
266+
return success;
231267
}
232268

233269
#pragma mark - Forms

ios/RCTPSPDFKit/RCTPSPDFKitViewManager.m

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,39 @@ @implementation RCTPSPDFKitViewManager
7676

7777
RCT_EXPORT_VIEW_PROPERTY(onStateChanged, RCTBubblingEventBlock)
7878

79-
RCT_EXPORT_METHOD(enterAnnotationCreationMode:(nonnull NSNumber *)reactTag) {
79+
RCT_EXPORT_METHOD(enterAnnotationCreationMode:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
8080
dispatch_async(dispatch_get_main_queue(), ^{
8181
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
82-
[component enterAnnotationCreationMode];
82+
BOOL success = [component enterAnnotationCreationMode];
83+
if (success) {
84+
resolve(@(success));
85+
} else {
86+
reject(@"error", @"Failed to enter annotation creation mode.", nil);
87+
}
8388
});
8489
}
8590

86-
RCT_EXPORT_METHOD(exitCurrentlyActiveMode:(nonnull NSNumber *)reactTag) {
91+
RCT_EXPORT_METHOD(exitCurrentlyActiveMode:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
8792
dispatch_async(dispatch_get_main_queue(), ^{
8893
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
89-
[component exitCurrentlyActiveMode];
94+
BOOL success = [component exitCurrentlyActiveMode];
95+
if (success) {
96+
resolve(@(success));
97+
} else {
98+
reject(@"error", @"Failed to exit currently active mode.", nil);
99+
}
90100
});
91101
}
92102

93-
RCT_EXPORT_METHOD(saveCurrentDocument:(nonnull NSNumber *)reactTag) {
103+
RCT_EXPORT_METHOD(saveCurrentDocument:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
94104
dispatch_async(dispatch_get_main_queue(), ^{
95105
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
96-
[component saveCurrentDocument];
106+
BOOL success = [component saveCurrentDocument];
107+
if (success) {
108+
resolve(@(success));
109+
} else {
110+
reject(@"error", @"Failed to save document.", nil);
111+
}
97112
});
98113
}
99114

@@ -109,10 +124,27 @@ @implementation RCTPSPDFKitViewManager
109124
});
110125
}
111126

112-
RCT_EXPORT_METHOD(addAnnotation:(id)jsonAnnotation reactTag:(nonnull NSNumber *)reactTag) {
127+
RCT_EXPORT_METHOD(addAnnotation:(id)jsonAnnotation reactTag:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
113128
dispatch_async(dispatch_get_main_queue(), ^{
114129
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
115-
[component addAnnotation:jsonAnnotation];
130+
BOOL success = [component addAnnotation:jsonAnnotation];
131+
if (success) {
132+
resolve(@(success));
133+
} else {
134+
reject(@"error", @"Failed to add annotation.", nil);
135+
}
136+
});
137+
}
138+
139+
RCT_EXPORT_METHOD(removeAnnotation:(id)jsonAnnotation reactTag:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
140+
dispatch_async(dispatch_get_main_queue(), ^{
141+
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
142+
BOOL success = [component removeAnnotation:jsonAnnotation];
143+
if (success) {
144+
resolve(@(success));
145+
} else {
146+
reject(@"error", @"Failed to remove annotation.", nil);
147+
}
116148
});
117149
}
118150

@@ -128,10 +160,15 @@ @implementation RCTPSPDFKitViewManager
128160
});
129161
}
130162

131-
RCT_EXPORT_METHOD(addAnnotations:(id)jsonAnnotations reactTag:(nonnull NSNumber *)reactTag) {
163+
RCT_EXPORT_METHOD(addAnnotations:(id)jsonAnnotations reactTag:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
132164
dispatch_async(dispatch_get_main_queue(), ^{
133165
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
134-
[component addAnnotations:jsonAnnotations];
166+
BOOL success = [component addAnnotations:jsonAnnotations];
167+
if (success) {
168+
resolve(@(success));
169+
} else {
170+
reject(@"error", @"Failed to add annotations.", nil);
171+
}
135172
});
136173
}
137174

samples/Catalog/Catalog.ios.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ class ProgrammaticAnnotations extends Component {
593593
},
594594
opacity: 1,
595595
pageIndex: 0,
596+
name: "A167811E-6D10-4546-A147-B7AD775FE8AC",
596597
strokeColor: "#AA47BE",
597598
type: "pspdfkit/ink",
598599
v: 1
@@ -602,6 +603,20 @@ class ProgrammaticAnnotations extends Component {
602603
title="addAnnotation"
603604
/>
604605
</View>
606+
<View>
607+
<Button
608+
onPress={async () => {
609+
// Programmatically remove an existing ink annotation.
610+
const inkAnnotations = await this.refs.pdfView.getAnnotations(
611+
this.state.currentPageIndex,
612+
"pspdfkit/ink"
613+
);
614+
const firstInkAnnotation = inkAnnotations["annotations"][0];
615+
this.refs.pdfView.removeAnnotation(firstInkAnnotation);
616+
}}
617+
title="removeAnnotation"
618+
/>
619+
</View>
605620
<View>
606621
<Button
607622
onPress={() => {
@@ -635,6 +650,7 @@ class ProgrammaticAnnotations extends Component {
635650
},
636651
isDrawnNaturally: false,
637652
strokeColor: "#AA47BE",
653+
name: "A167811E-6D10-4546-A147-B7AD775FE8AC",
638654
updatedAt: "2018-07-30T15:34:48Z",
639655
pageIndex: 0,
640656
opacity: 1,

0 commit comments

Comments
 (0)