Some test text!
iOS / Guides / Config annotation tools
Annotation and PDF interaction is implemented within the open-source Tools.framework
. This includes annotation creation & selection, text selection, form filling and link following.
The behavior is implemented via a collection of "Tools": classes that derive from the abstract base class PTTool
and that are coordinated by a PTToolManager
. The PTToolManager
provides the ability to customize tool behavior, and enable/disable the ability for users to create or edit annotations (both in general and on an annotation type by annotation type basis).
To disable (or re-enable) the ability to create or edit annotations, options can be altered as shown below. When disabled, the relevant annotation tool is removed from the annotation toolbar , and from the UIMenuController
.
// disables all text annotation types (highlights, underlines, etc.)
toolManager.highlightAnnotationOptions.canCreate = false
toolManager.highlightAnnotationOptions.canEdit = false
toolManager.underlineAnnotationOptions.canCreate = false
toolManager.underlineAnnotationOptions.canEdit = false
toolManager.strikeOutAnnotationOptions.canCreate = false
toolManager.strikeOutAnnotationOptions.canEdit = false
toolManager.squigglyAnnotationOptions.canCreate = false
toolManager.squigglyAnnotationOptions.canEdit = false
Further control over annotation interaction behaviour via the PTToolManagerDelegate
protocol.
There are several methods that allow you to be notified of, and if desired modify or prevent, default behavior from occurring. For all methods, if false
is returned, then the default behavior will not occur.
-toolManager:shouldSelectAnnotation:onPageNumber:
This method is called just before an annotation is selected. The annotation object itself is available for the decision making process, and for further action if needed.
-toolManager:shouldShowMenu:forAnnotation:onPageNumber:
This method is called just before the selection popup menu is shown. The UIMenuController
object is passed so that menu items can be added or removed as required.
-toolManager:shouldHandleLinkAnnotation:orLinkInfo:onPageNumber:
This method is called just before a link is followed. The link is provided so that alternate action can be taken if required.
-toolManager:shouldSwitchToTool:
This method is called just before a tool is activated. The tool is available for the decision making process.
The sample code uses -toolManager:shouldShowMenu:forAnnotation:onPageNumber:
to restrict use of the UIMenuController
to copying and defining text found in the PDF. This is done by stopping the UIMenuController from popping up in any case other than selecting text, and by removing options to highlight/underline etc. from the selected text UIMenuController popup.
// PTToolManagerDelegate method implementation.
func toolManager(_ toolManager: PTToolManager, shouldShowMenu menuController: UIMenuController, forAnnotation annotation: PTAnnot, onPageNumber pageNumber: UInt) -> Bool {
// Only show quick menu for the text select tool.
if type(of: toolManager.tool) === TextSelectTool.self {
// Remove the annotation creation menu items.
menuController.menuItems = removeAnnotationItems(menuController.menuItems!)
return true;
} else {
return false;
}
}
func removeAnnotationItems(_ items: [UIMenuItem]) -> [UIMenuItem] {
let stringsToRemove = ["Highlight", "Underline", "Squiggly", "Strikeout"]
// Filter out menu items with titles matching specified strings.
return items.filter({ (menuItem) -> Bool in
return !stringsToRemove.contains(menuItem.title)
})
}
Default Menu Options | Customized Menu Options |
---|---|
Tools.framework
frequently creates new instances of objects defined within the framework (e.g. a new instance of PTAnnotEditTool
is created when a user taps on an annotation). In order to customize certain aspects of the default behavior, it is required to create and use a subclass of the built-in tool. To enable this without requiring source code modification, Tools.framework
includes a system to "inject" an externally defined subclass that will be used by the Tools.framework
during its normal operation. This is done via the PTOverrides
class as follows:
// EGAnnotEditTool is an externally defined class that derives from PTAnnotEditTool
PTOverrides.overrideClass(PTAnnotEditTool.self, withClass: EGAnnotEditTool.self);
Note that in order to be compatible with the external override system, the base class must conform to the PTOverridable
protocol.
Because Tools.framework
is open source, any and all changes are possible by editing the source code directly. The project is found in /Lib/Tools/src
.
If you customize the tools source code, you will likely want to use a universal framework (one that contains architectures for both simulators and devices), which is not done automatically by Xcode. The Tools project includes a custom script step that automatically creates a universal framework, located in a folder next to the default build location, with the name {Debug,Release}-universal
.
(Building a universal framework also be done manually by first building for device, then simulator, and using the terminal command xcrun -sdk iphoneos lipo -create
to merge the binaries (Tools.framework/Tools
) into a universal binary.)
Trial setup questions? Ask experts on Discord
Need other help? Contact Support
Pricing or product questions? Contact Sales