The dock provides quick access to content libraries and editing tools, appearing at the bottom of the editor interface. This guide shows you how to customize dock items and their layout to match your app’s content strategy and user workflow. While examples use the Design Editor, the same configuration principles apply to all editor solutions.
Explore a complete code sample on GitHub.
Dock Architecture#
The dock displays horizontally at the bottom of the editor and provides quick access to content libraries and editing tools. It adapts its content based on the selected editor solution.
Key Components:
Dock.Item
- Protocol that all dock items conform toDock.Button
- Pre-built button implementation with icon and titleDock.Context
- Provides access to the engine, asset library, and event handler- Custom Items - Create fully custom components by implementing
Dock.Item
Configuration#
Dock customization uses SwiftUI modifiers in the .imgly
namespace. You can configure the complete item list or modify the default items.
Available modifiers:
-
dockItems
- Define the complete list of dock items and their order. Items are only displayed whenisVisible(_:)
returnstrue
. -
modifyDockItems
- Modify the default item list by adding, replacing, or removing specific items without rebuilding the entire configuration.
The Dock.Context
provides access to the engine, asset library, and event handler. Use this for advanced customization logic and to maintain consistency with the current editor state.
Default Dock Items#
Each editor solution has its own default dock configuration optimized for its content workflow:
These are the default items recommended to be used with the Design Editor:
.imgly.dockItems { _ in Dock.Buttons.elementsLibrary() Dock.Buttons.imglyPhotoRoll() Dock.Buttons.systemCamera() Dock.Buttons.imagesLibrary() Dock.Buttons.textLibrary() Dock.Buttons.shapesLibrary() Dock.Buttons.stickersLibrary() Dock.Buttons.resize()}
These are the default items recommended to be used with the Photo Editor:
.imgly.dockItems { _ in Dock.Buttons.adjustments() Dock.Buttons.filter() Dock.Buttons.effect() Dock.Buttons.blur() Dock.Buttons.crop() Dock.Buttons.textLibrary() Dock.Buttons.shapesLibrary() Dock.Buttons.stickersLibrary()}
These are the default items recommended to be used with the Video Editor:
.imgly.dockItems { _ in Dock.Buttons.imglyPhotoRoll() Dock.Buttons.imglyCamera() Dock.Buttons.overlaysLibrary() Dock.Buttons.textLibrary() Dock.Buttons.stickersAndShapesLibrary() Dock.Buttons.audioLibrary() Dock.Buttons.voiceover() Dock.Buttons.reorder() Dock.Buttons.resize()}
Apparel Editor and Postcard Editor don’t have predefined dock items by default, but you can customize them by providing your own dock configuration using .imgly.dockItems
. This will also enable the use of .imgly.modifyDockItems
for fine-tuning.
Modify Dock Items#
Use the .imgly.modifyDockItems
modifier to adjust the default item list without rebuilding the entire configuration:
.imgly.modifyDockItems { context, items in
Parameters:
context
- provides access to the engine, asset library, and event handleritems
- mutable array of dock items that can be modified
Available modification operations:
addFirst
- prepends newDock.Item
s:
items.addFirst { Dock.Button(id: "my.package.dock.button.first") { context in print("First Button action") } label: { context in Label("First Button", systemImage: "arrow.backward.circle") }}
addLast
- appends newDock.Item
s:
items.addLast { Dock.Button(id: "my.package.dock.button.last") { context in print("Last Button action") } label: { context in Label("Last Button", systemImage: "arrow.forward.circle") }}
addAfter
- adds newDock.Item
s right after the item with the provided id:
items.addAfter(id: Dock.Buttons.ID.imglyPhotoRoll) { Dock.Button(id: "my.package.dock.button.afterIMGLYPhotoRoll") { context in print("After IMGLY Photo Roll action") } label: { context in Label("After IMGLY Photo Roll", systemImage: "arrow.forward.square") }}
addBefore
- adds newDock.Item
s right before the item with the provided id:
items.addBefore(id: Dock.Buttons.ID.systemCamera) { Dock.Button(id: "my.package.dock.button.beforeSystemCamera") { context in print("Before Camera action") } label: { context in Label("Before Camera", systemImage: "arrow.backward.square") }}
replace
- replaces theDock.Item
with the provided id with newDock.Item
s:
items.replace(id: Dock.Buttons.ID.textLibrary) { Dock.Button(id: "my.package.dock.button.replacedTextLibrary") { context in print("Replaced Text action") } label: { context in Label("Replaced Text ", systemImage: "arrow.uturn.down.square") }}
remove
- removes theDock.Item
with the provided id:
items.remove(id: Dock.Buttons.ID.shapesLibrary)
Dock.Item Configuration#
Each Dock.Item
conforms to EditorComponent
. Its id
must be unique which is a requirement of the underlying SwiftUI ForEach
type.
Depending on your needs there are multiple ways to define an item. In this example, we demonstrate your options with increasing complexity.
Use Predefined Buttons#
The most basic option is to use our predefined buttons which are provided in the nested Dock.Buttons.
namespace. All available predefined buttons are listed below.
Dock.Buttons.elementsLibrary()
Customize Predefined Buttons#
All parameters of our predefined buttons are initialized with default values which allows you to change any of them if needed to finetune the button’s behavior and style:
Dock.Buttons.imagesLibrary( action: { context in context.eventHandler.send(.openSheet(type: .libraryAdd { context.assetLibrary.imagesTab })) }, title: { context in Text("Image") }, icon: { context in Image.imgly.addImage }, isEnabled: { context in true }, isVisible: { context in true },)
Available parameters:
-
action
- the action to perform when the user triggers the button. In this example, the event handler is used to open a sheet with the Asset Library for adding an image. -
title
- the titleView
that should be used to label the button. Don’t encode the visibility in this view. UseisVisible
instead. In this example, aText
view is used. -
icon
- the iconView
that should be used to label the button. Don’t encode the visibility in this view. UseisVisible
instead. You can use any custom icon or system image. We also provide icon images in theImage.imgly
namespace for convenience. -
isEnabled
- whether the button is enabled. In this example, true is always used. -
isVisible
- whether the button should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in thetitle
andicon
views. In this example, true is always used.
Create New Buttons#
If our predefined buttons don’t fit your needs you can create your own:
Dock.Button( id: "my.package.dock.button.newButton",) { context in print("New Button action")} label: { context in Label("New Button", systemImage: "star.circle")} isEnabled: { context in true} isVisible: { context in true}
Required and optional parameters:
-
id
- the unique id of the button. This parameter is required. -
action
- the action to perform when the user triggers the button. This parameter is required. -
label
- aView
that describes the purpose of the button’saction
. Don’t encode the visibility in this view. UseisVisible
instead. This parameter is required. -
isEnabled
- whether the button is enabled. By default, true is always used. -
isVisible
- whether the button should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in thelabel
view. By default, true is always used.
Create New Custom Items#
If you need something completely custom you can use arbitrary views as items.
Therefore, you need to conform your type to the Dock.Item
protocol:
private struct CustomDockItem: Dock.Item { var id: EditorComponentID { "my.package.dock.newCustomItem" }
func body(_ context: Dock.Context) throws -> some View { ZStack { RoundedRectangle(cornerRadius: 10) .fill(.conicGradient(colors: [.red, .yellow, .green, .cyan, .blue, .purple, .red], center: .center)) Text("New Custom Item") .padding(4) } .onTapGesture { print("New Custom Item action") } }
func isVisible(_ context: Dock.Context) throws -> Bool { true }}
Then use it in your dock items:
CustomDockItem()
Protocol requirements:
-
var id: EditorComponentID { get }
- the unique id of the item. This property is required. -
func body(_: Dock.Context) throws -> some View
- the body of your view. Don’t encode the visibility in this view. UseisVisible
instead. This property is required. -
func isVisible(_: Dock.Context) throws -> Bool
- whether the item should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in thebody
view. By default, true is always used.
List of Available Dock.Buttons#
All predefined buttons are available as static functions in the Dock.Buttons
namespace. Each function returns a Dock.Button
with default parameters that you can customize as shown in the Customize Predefined Buttons section.
Button | ID | Description |
---|---|---|
Dock.Buttons.elementsLibrary | Dock.Buttons.ID.elementsLibrary | Opens library sheet with elements via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.overlaysLibrary | Dock.Buttons.ID.overlaysLibrary | Opens library sheet with overlays via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.stickersAndShapesLibrary | Dock.Buttons.ID.stickersAndShapesLibrary | Opens library sheet with stickers and shapes via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.imagesLibrary | Dock.Buttons.ID.imagesLibrary | Opens library sheet with images via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.textLibrary | Dock.Buttons.ID.textLibrary | Opens library sheet with text via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.shapesLibrary | Dock.Buttons.ID.shapesLibrary | Opens library sheet with shapes via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.stickersLibrary | Dock.Buttons.ID.stickersLibrary | Opens library sheet with stickers via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.audioLibrary | Dock.Buttons.ID.audioLibrary | Opens library sheet with audio via editor event .openSheet . By default, the corresponding library is picked from the Asset Library. |
Dock.Buttons.systemPhotoRoll | Dock.Buttons.ID.systemPhotoRoll | Opens the system photo roll via editor event .addFromSystemPhotoRoll . |
Dock.Buttons.imglyPhotoRoll | Dock.Buttons.ID.imglyPhotoRoll | Opens the IMG.LY photo roll via editor event .addFromIMGLYPhotoRoll . |
Dock.Buttons.systemCamera | Dock.Buttons.ID.systemCamera | Opens the system camera via editor event .addFromSystemCamera . |
Dock.Buttons.imglyCamera | Dock.Buttons.ID.imglyCamera | Opens the IMG.LY camera via editor event .addFromIMGLYCamera . |
Dock.Buttons.voiceover | Dock.Buttons.ID.voiceover | Opens voiceover sheet via editor event .openSheet . |
Dock.Buttons.reorder | Dock.Buttons.ID.reorder | Opens reorder sheet via editor event .openSheet . |
Dock.Buttons.adjustments | Dock.Buttons.ID.adjustments | Opens adjustment sheet via editor event .openSheet . |
Dock.Buttons.filter | Dock.Buttons.ID.filter | Opens filter sheet via editor event .openSheet . |
Dock.Buttons.effect | Dock.Buttons.ID.effect | Opens effect sheet via editor event .openSheet . |
Dock.Buttons.blur | Dock.Buttons.ID.blur | Opens blur sheet via editor event .openSheet . |
Dock.Buttons.crop | Dock.Buttons.ID.crop | Opens crop sheet via editor event .openSheet . |
Dock.Buttons.resize | Dock.Buttons.ID.resize | Opens resize sheet via editor event .openSheet . |
Dock.Buttons.assetLibrary | Dock.Buttons.ID.assetLibrary | Opens asset library sheet via editor event .openSheet . |