Manage in-meeting annotation
The code on this page works with either the default UI or the custom UI.
When users start sharing their screens, others can annotate on top of the shared video feed. Through the SDK, you can manage many settings related to the appearance and availability of annotation.
Annotation settings
Before starting to annotate, check the meeting settings in the web portal to confirm that it is currently enabled. Check synchronously through the annotation controller, or receive updates asynchronously through the ZoomSDKASControllerDelegate.
var customizedAnnotation: ZoomSDKCustomizedAnnotation? = nil
var shareElement: ZoomSDKShareElement? = nil // shareElement is needed to annotate on the remote user's screen share. Or to annotation on your own share, keep this nil.
// In your ViewController, you need to add the ZoomSDKASControllerDelegate to receive share-related callbacks and also ZoomSDKCustomizedAnnotationCtrlDelegate to receive its annotation callback
if let annotationShareController = ZoomSDK.shared().getMeetingService()?.getASController(), let customizedAnnotationCtr = annotationShareController.getCustomizedAnnotationCtr() {
annotationShareController.delegate = self
customizedAnnotationCtr.delegate = self
/*
To annotate on the local user's screen sharing:
1. customizedAnnotation must be nil
2. shareElement must be nil OR create a shareElement with sharingID = 0
*/
if customizedAnnotationCtr.createCustomizedAnnotation(&customizedAnnotation, shareElement: &shareElement) == ZoomSDKError_Success, let customizedAnnotation = customizedAnnotation {
customizedAnnotation.delegate = self
}
/*
OR
To annotate on a remote user's screen share, you must have first already created the ZoomSDKShareElement that you are subscribing to. The steps are similar to how screen sharing works:
1. Identify the remote user's screen share through its shareSourceID. This can be obtained in the onSharingStatusChanged(_ shareInfo: ZoomSDKSharingSourceInfo)'s callback and using the shareInfo.shareSourceID
2. Create a ZoomSDKShareElement based on the subscribed screen CGRect size, sharingID = shareSourceID, viewMode and etc. Then, add the ZoomSDKShareElement shareView to your own view.
4. Continue with the steps below for annotation
*/
if let shareElement = shareElement {
if customizedAnnotationCtr.createCustomizedAnnotation(&customizedAnnotation, shareElement: shareElement) == ZoomSDKError_Success, let customizedAnnotation = customizedAnnotation {
customizedAnnotation.delegate = self
}
}
}
// Conform your ViewController to the ZoomSDKCustomizedAnnotationCtrlDelegate and ZoomSDKCustomizedAnnotationDelegate protocol. Conform to the ZoomSDKASControllerDelegate if you also want to receive share-related callbacks.
extension ViewController: ZoomSDKCustomizedAnnotationCtrlDelegate, ZoomSDKCustomizedAnnotationDelegate {
func onAnnotationSupportPropertyChanged(forCustom isSupportAnnotation: Bool, shareSourceID: UInt32) {
if isSupportAnnotation {
// Annotations are enabled
}
// currentShareID = shareSourceID
}
func onAnnotationCleanUp(_ annotation: ZoomSDKCustomizedAnnotation) {
}
func onAnnotationStatusChanged(_ element: ZoomSDKShareElement?, status: AnnotationStatus) {
}
func onAnnotationToolChanged(_ tool: AnnotationToolType) {
}
}
// To determine if annotations can be performed manually
if let customizedAnnotationCtr = ZoomSDK.shared().getMeetingService()?.getASController().getCustomizedAnnotationCtr() {
var canDoAnno = ObjCBool(true)
if let customizedAnnotation = customizedAnnotation, customizedAnnotationCtr.canDo(customizedAnnotation, canAnnotate: &canDoAnno) == ZoomSDKError_Success, canDoAnno.boolValue {
// Annotations can be performed
}
}
// In your ViewController.h, you need to conform it to the ZoomSDKASControllerDelegate protocol
@interface ViewController : NSWindowController <ZoomSDKASControllerDelegate, ZoomSDKCustomizedAnnotationDelegate, ZoomSDKCustomizedAnnotationCtrlDelegate> {
}
// In your ViewController.m, you need to add the relevant delegates callbacks first to receive the callback later
ZoomSDKCustomizedAnnotation *customizedAnnotation = nil;
ZoomSDKShareElement = nil; // shareElement is needed to annotate on remote user's screen share. Or to annotation on your own share, keep this nil.
ZoomSDKASController *annotationShareController =
[[[ZoomSDK sharedSDK] getMeetingService] getASController];
if (annotationShareController) {
ZoomSDKCustomizedAnnotationCtr *customizedAnnotationCtr =
[annotationShareController getCustomizedAnnotationCtr];
if (customizedAnnotationCtr) {
annotationShareController.delegate = self;
customizedAnnotationCtr.delegate = self;
// To annotate on the local user's screen sharing - customizedAnnotation and shareElement must be nil
ZoomSDKError error =
[customizedAnnotationCtr createCustomizedAnnotation:&customizedAnnotation
ShareElement:shareElement];
if (error == ZoomSDKError_Success && customizedAnnotation) {
customizedAnnotation.delegate = self;
}
/*
OR
To annotate on a remote user's screen share, you must have first already created the ZoomSDKShareElement that you are subscribing to. The steps are similar to how screen sharing works:
1. Identify the remote user's screen share through its shareSourceID. This can be obtained in the onSharingStatusChanged(_ shareInfo: ZoomSDKSharingSourceInfo)'s callback and using the shareInfo.shareSourceID
2. Create a ZoomSDKShareElement based on the subscribed screen CGRect size, sharingID = shareSourceID, viewMode and etc. Then, add the ZoomSDKShareElement shareView to your own view.
4. Continue with the steps below for annotation
*/
if (shareElement != nil) {
ZoomSDKError error =
[customizedAnnotationCtr createCustomizedAnnotation:&customizedAnnotation
ShareElement:shareElement];
if (error == ZoomSDKError_Success && customizedAnnotation) {
customizedAnnotation.delegate = self;
}
}
}
}
- (void)onAnnotationSupportPropertyChangedForCustom:(BOOL)isSupportAnnotation shareSourceID:(unsigned int)shareSourceID {
if (isSupportAnnotation) {
// Annotations are enabled
}
// currentShareID = shareSourceID;
}
- (void)onAnnotationCleanUp:(ZoomSDKCustomizedAnnotation *)annotation {
}
- (void)onAnnotationStatusChanged:(ZoomSDKShareElement *)element Status:(AnnotationStatus)status {
}
- (void)onAnnotationToolChanged:(AnnotationToolType)tool {
}
// To determine if annotations can be performed manually
ZoomSDKCustomizedAnnotationCtr *customizedAnnotationCtr =
[[[[ZoomSDK sharedSDK] getMeetingService] getASController] getCustomizedAnnotationCtr];
if (customizedAnnotationCtr) {
BOOL canDoAnno = NO;
if (customizedAnnotation && [customizedAnnotationCtr canDoAnnotation:customizedAnnotation canAnnotate:&canDoAnno] == ZoomSDKError_Success && canDoAnno) {
// Annotations can be performed
}
}
If the current user is sharing their screen, they can enable or disable viewers to annotate the shared screen.
var canDisableAnnotation = ObjCBool(false)
if customizedAnnotationCtr.canDisableViewerAnnotation(customizedAnnotation, canDisabled: &canDisableAnnotation) == ZoomSDKError_Success && canDisableAnnotation.boolValue {
var isAnnotationLocked = ObjCBool(true)
if customizedAnnotationCtr.isViewerAnnotationLocked(customizedAnnotation, isLocked: &isAnnotationLocked) == ZoomSDKError_Success && isAnnotationLocked.boolValue {
// Depending on the isAnnotationLocked's Bool value, then disable/enable viewer annotation
customizedAnnotationCtr.disableViewerAnnotation(customizedAnnotation, disable: false) // Or true
}
}
BOOL canDisableAnnotation = NO;
if ([annotationShareController canDisableViewerAnnotation:ScreenType_First canDisabled:&canDisableAnnotation] == ZoomSDKError_Success && canDisableAnnotation) {
BOOL isAnnotationLocked;
if ([annotationShareController isViewerAnnotationLocked:ScreenType_First isLocked:&isAnnotationLocked] == ZoomSDKError_Success && isAnnotationLocked) {
[annotationShareController disableViewerAnnotation:ScreenType_First disable:NO]; // Or YES
}
}
Control annotation properties
In default UI mode, the annotation toolbar displays only after using the ZoomSDKASController to manage annotations.
To start annotating, call startAnnotation. When annotation is finished, use stopAnnotation.
if annotationShareController.startAnnotation(ScreenType_First) == ZoomSDKError_Success {
// You can begin using the annotation tool
}
annotationShareController.stopAnnotation(ScreenType_First)
if ([annotationShareController startAnnotation:ScreenType_First] == ZoomSDKError_Success) {
// You can begin using the annotation tool
}
[annotationShareController stopAnnotation:ScreenType_First];
Optionally, after verifying that annotation started based on the return value of startAnnotation, modify the annotation appearance programmatically.
annotationController.setColor(1, green: 1, blue: 1, on: ScreenType_First) // red, green and blue: Float (0 - 255)
annotationController.setTool(AnnotationToolType_Pen, on: ScreenType_First) // type: AnnotationToolType
annotationController.setLineWidth(1, on: ScreenType_First) // lineWidth: Int
[annotationController setColor:1 green:1 blue:1 onScreen:ScreenType_First]; // red, green and blue: Float (0 - 255)
[annotationController setTool:AnnotationToolType_Pen onScreen:ScreenType_First]; // type: AnnotationToolType
[annotationController setLineWidth:1 onScreen:ScreenType_First]; // lineWidth: Int
Interact with annotations that users create by undoing, redoing or clearing annotations.
annotationController.undo(ScreenType_First)
annotationController.redo(ScreenType_First)
annotationController.clear(AnnotationClearType_All, on: ScreenType_First) // AnnotationClearType: All, self, others.
ZoomSDKAnnotationController *annotationController = [annotationShareController getAnnotationController];
[annotationController undo:ScreenType_First];
[annotationController redo:ScreenType_First];
[annotationController clear:AnnotationClearType_All onScreen:ScreenType_First];