Configure Annotation Presets on iOS

PSPDFKit has default values for some annotation properties (e.g. colors and line widths for ink annotations). It sometimes also has multiple styles per annotation type (“variants”).

This is all handled in AnnotationStyleManager, which is a global singleton. You can access it with SDK.shared.styleManager.

The current set of defaults is configured on the first run and subsequently saved in UserDefaults:

public func setupDefaultStylesIfNeeded() {
    // Line widths.
    setLastUsedValue(4, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .ink))
    setLastUsedValue(4, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkPen))
    setLastUsedValue(30, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkHighlighter))
    setLastUsedValue(5, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .square))
    setLastUsedValue(5, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .circle))
    setLastUsedValue(3, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .polygon))
    setLastUsedValue(3, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .polygon, variant: .cloud))
    setLastUsedValue(3, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .line))
    setLastUsedValue(4, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .line, variant: .lineArrow))
    setLastUsedValue(3, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .polyLine))
    setLastUsedValue(3, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .signature))
    setLastUsedValue(10, forProperty: "lineWidth", forKey: Annotation.ToolVariantID(tool: .eraser))

    // Colors.
    let black = UIColor.black
    let blue = UIColor(red: 0.141, green: 0.573, blue: 0.984, alpha: 1) // #2492FB
    let red = UIColor(red: 0.871, green: 0.278, blue: 0.31, alpha: 1) // #DE474F
    let yellow = UIColor(red: 0.996, green: 0.91, blue: 0.196, alpha: 1) // #FEE832

    setLastUsedValue(yellow, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .highlight))
    setLastUsedValue(black, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .underline))
    setLastUsedValue(red, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .squiggly))
    setLastUsedValue(red, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .strikeOut))

    // Set ink and variants.
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .ink))
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkMagic))
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkPen))
    setLastUsedValue(yellow, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkHighlighter))
    setLastUsedValue(0.5, forProperty: "alpha", forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkHighlighter))

    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .square))
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .circle))
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .polygon))
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .polygon, variant: .cloud))
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .line))
    setLastUsedValue(red, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .line, variant: .lineArrow))
    setLastUsedValue(blue, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .polyLine))
    setLastUsedValue(black, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .signature))
    setLastUsedValue(black, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .freeText))
    setLastUsedValue(red, forProperty: "color", forKey: Annotation.ToolVariantID(tool: .redaction))

    // Arrow style.
    setLastUsedValue(AbstractLineAnnotation.EndType.openArrow.rawValue, forProperty: "lineEnd2", forKey: Annotation.ToolVariantID(tool: .line, variant: .lineArrow))

    // Fonts.
    setLastUsedValue(12, forProperty: "fontSize", forKey: Annotation.ToolVariantID(tool: .freeText))
    setLastUsedValue("Helvetica", forProperty: "fontName", forKey: Annotation.ToolVariantID(tool: .freeText))

    // Border effect.
    setLastUsedValue(Annotation.BorderEffect.noEffect, forProperty: "borderEffect", forKey: Annotation.ToolVariantID(tool: .circle))
    setLastUsedValue(Annotation.BorderEffect.noEffect, forProperty: "borderEffect", forKey: Annotation.ToolVariantID(tool: .square))
    setLastUsedValue(Annotation.BorderEffect.noEffect, forProperty: "borderEffect", forKey: Annotation.ToolVariantID(tool: .polygon))
    setLastUsedValue(Annotation.BorderEffect.cloudy, forProperty: "borderEffect", forKey: Annotation.ToolVariantID(tool: .polygon, variant: .cloud))
    setLastUsedValue(2, forProperty: "borderEffectIntensity", forKey: Annotation.ToolVariantID(tool: .polygon, variant: .cloud))

    // Blend mode.
    setLastUsedValue(CGBlendMode.multiply.rawValue, forProperty: "blendMode", forKey: Annotation.ToolVariantID(tool: .highlight))
    setLastUsedValue(CGBlendMode.multiply.rawValue, forProperty: "blendMode", forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkHighlighter))

    // Fill color.
    setLastUsedValue(black, forProperty: "fillColor", forKey: Annotation.ToolVariantID(tool: .redaction))

    // Outline color.
    setLastUsedValue(red, forProperty: "outlineColor", forKey: Annotation.ToolVariantID(tool: .redaction))
    setLastUsedValue(nil, forProperty: "overlayText", forKey: Annotation.ToolVariantID(tool: .redaction))
    setLastUsedValue(false, forProperty: "repeatOverlayText", forKey: Annotation.ToolVariantID(tool: .redaction))
}
- (void)setupDefaultStylesIfNeeded {
    // Line widths.
    [self setLastUsedValue:@(4) forProperty:"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, nil)];
    [self setLastUsedValue:@(4) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, nil)];
    [self setLastUsedValue:@(4) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkPen)];
    [self setLastUsedValue:@(30) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkHighlighter)];
    [self setLastUsedValue:@(5) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringSquare, nil)];
    [self setLastUsedValue:@(5) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringCircle, nil)];
    [self setLastUsedValue:@(3) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolygon, nil)];
    [self setLastUsedValue:@(3) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolygon, PSPDFAnnotationVariantStringPolygonCloud)];
    [self setLastUsedValue:@(3) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringLine, nil)];
    [self setLastUsedValue:@(4) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringLine, PSPDFAnnotationVariantStringLineArrow)];
    [self setLastUsedValue:@(3) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolyLine, nil)];
    [self setLastUsedValue:@(2) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringSignature, nil)];
    [self setLastUsedValue:@(10) forProperty:@"lineWidth" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringEraser, nil)];

    // Colors.
    let black = UIColor.blackColor;
    let blue = [UIColor colorWithRed:0.141f green:0.573f blue:0.984f alpha:1.0f]; // #2492FB
    let red = [UIColor colorWithRed:0.871f green:0.278f blue:0.31f alpha:1.0f]; // #DE474F
    let yellow = [UIColor colorWithRed:0.996f green:0.91f blue:0.196f alpha:1.0f]; // #FEE832
    [self setLastUsedValue:yellow forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringHighlight, nil)];
    [self setLastUsedValue:black forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringUnderline, nil)];
    [self setLastUsedValue:red forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringSquiggly, nil)];
    [self setLastUsedValue:red forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringStrikeOut, nil)];

    // Set ink and variants.
    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, nil)];
    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkMagic)];
    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkPen)];
    [self setLastUsedValue:yellow forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkHighlighter)];
    [self setLastUsedValue:@(0.5) forProperty:@"alpha" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkHighlighter)];

    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringSquare, nil)];
    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringCircle, nil)];

    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolygon, nil)];
    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolygon, PSPDFAnnotationVariantStringPolygonCloud)];

    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringLine, nil)];
    [self setLastUsedValue:red forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringLine, PSPDFAnnotationVariantStringLineArrow)];
    [self setLastUsedValue:blue forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolyLine, nil)];
    [self setLastUsedValue:black forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringSignature, nil)];
    [self setLastUsedValue:black forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringFreeText, nil)];
    [self setLastUsedValue:red forProperty:@"color" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringRedaction, nil)];

    // Arrow speciality.
    [self setLastUsedValue:@(PSPDFLineEndTypeOpenArrow) forProperty:@"lineEnd2" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringLine, PSPDFAnnotationVariantStringLineArrow)];

    // Fonts.
    [self setLastUsedValue:@(12) forProperty:@"fontSize" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringFreeText, nil)];
    [self setLastUsedValue:@"Helvetica" forProperty:@"fontName" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringFreeText, nil)];

    // Border effect.
    [self setLastUsedValue:@(PSPDFAnnotationBorderEffectNoEffect) forProperty:@"borderEffect" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringCircle, nil)];
    [self setLastUsedValue:@(PSPDFAnnotationBorderEffectNoEffect) forProperty:@"borderEffect" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringSquare, nil)];
    [self setLastUsedValue:@(PSPDFAnnotationBorderEffectNoEffect) forProperty:@"borderEffect" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolygon, nil)];
    [self setLastUsedValue:@(PSPDFAnnotationBorderEffectCloudy) forProperty:@"borderEffect" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolygon, PSPDFAnnotationVariantStringPolygonCloud)];
    [self setLastUsedValue:@(2) forProperty:@"borderEffectIntensity" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringPolygon, PSPDFAnnotationVariantStringPolygonCloud)];

    // Blend mode.
    [self setLastUsedValue:@(kCGBlendModeMultiply) forProperty:@"blendMode" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringHighlight, nil)];
    [self setLastUsedValue:@(kCGBlendModeMultiply) forProperty:@"blendMode" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkHighlighter)];

    // Fill color.
    [self setLastUsedValue:black forProperty:@"fillColor" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringRedaction, nil)];

    // Outline color.
    [self setLastUsedValue:red forProperty:@"outlineColor" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringRedaction, nil)];
    [self setLastUsedValue:nil forProperty:@"overlayText" forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringRedaction, nil)];
}

You can use this call somewhere in your code to update these defaults. We suggest you add a custom key in NSUserDefaults and store your overrides under it so that they aren’t mixed with the changes to the default values that users make:

/**
  Convenience method. Will set the last used style for `key` and `styleProperty`.
  - parameter value: might be a boxed `CGFloat`, color, or whatever matches the property.
  `styleProperty` is the `NSString` name for the property (e.g. `NSStringFromSelector(@ selector(fontSize))`.
  `key` is an annotation string, e.g. `AnnotationStringFreeText`.
  Uses `AnnotationStyle.Kind.lastUsed` and calls `add(_:forKey:)`.
*/
public func setLastUsedValue(_ value: Any?, forProperty styleProperty: String, forKey key: Annotation.ToolVariantID)
/**
  Convenience method. Will set the last used style for `key` and `styleProperty`.
  @param value might be a boxed `CGFloat`, color, or whatever matches the property.
  `styleProperty` is the `NSString` name for the property (e.g. `NSStringFromSelector(@ selector(fontSize))`.
  `key` is an `id` constructed from an annotation's type and variant using the `PSPDFAnnotationStateVariantIDMake` function, e.g. `PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringLine, PSPDFAnnotationVariantStringLineArrow)`.
  Uses `PSPDFAnnotationStyleTypeLastUsed` and calls `addStyle:forKey`.
*/
- (void)setLastUsedValue:(nullable id)value forProperty:(NSString *)styleProperty forKey:(PSPDFAnnotationString)key;

Example

Here’s how to set a few properties of ink and highlight annotations:

let drawingColor = UIColor.green
let highlightingColor = UIColor.red
let colorProperty = "color"
let alphaProperty = "alpha"
let lineWidthProperty = "lineWidth"

SDK.shared.styleManager.setLastUsedValue(drawingColor, forProperty: colorProperty, forKey: Annotation.ToolVariantID(tool: .ink))
SDK.shared.styleManager.setLastUsedValue(drawingColor, forProperty: colorProperty, forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkPen))

// Set highlight color.
SDK.shared.styleManager.setLastUsedValue(highlightingColor, forProperty: colorProperty, forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkHighlighter))
SDK.shared.styleManager.setLastUsedValue(0.5, forProperty: alphaProperty, forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkHighlighter))

// Set line width of ink annotations.
SDK.shared.styleManager.setLastUsedValue(5, forProperty: lineWidthProperty, forKey: Annotation.ToolVariantID(tool: .ink))
SDK.shared.styleManager.setLastUsedValue(5, forProperty: lineWidthProperty, forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkPen))

// Set line width of highlight annotations.
SDK.shared.styleManager.setLastUsedValue(20, forProperty: lineWidthProperty, forKey: Annotation.ToolVariantID(tool: .ink, variant: .inkHighlighter))
UIColor *drawingColor = [UIColor greenColor];
UIColor *highlightingColor = [UIColor redColor];
NSString *colorProperty = NSStringFromSelector(@selector(color));
NSString *alphaProperty = NSStringFromSelector(@selector(alpha));
NSString *lineWidthProperty = NSStringFromSelector(@selector(lineWidth));

// Set ink color.
[PSPDFKitGlobal.sharedInstance.styleManager setLastUsedValue:drawingColor forProperty:colorProperty forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, nil)];
[PSPDFKitGlobal.sharedInstance.styleManager setLastUsedValue:drawingColor forProperty:colorProperty forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkPen)];

// Set highlight color.
[PSPDFKitGlobal.sharedInstance.styleManager setLastUsedValue:highlightingColor forProperty:colorProperty forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkHighlighter)];
[PSPDFKitGlobal.sharedInstance.styleManager setLastUsedValue:@(0.5f) forProperty:alphaProperty forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkHighlighter)];

// Set line width of ink annotations.
[PSPDFKitGlobal.sharedInstance.styleManager setLastUsedValue:@(5) forProperty:lineWidthProperty forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, nil)];
[PSPDFKitGlobal.sharedInstance.styleManager setLastUsedValue:@(5) forProperty:lineWidthProperty forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkPen)];

// Set line width of highlight annotations.
[PSPDFKitGlobal.sharedInstance.styleManager setLastUsedValue:@(20) forProperty:lineWidthProperty forKey:PSPDFAnnotationStateVariantIDMake(PSPDFAnnotationStringInk, PSPDFAnnotationVariantStringInkHighlighter)];