In this example, we will show you how to make navigation bar configurations for the mobile editor. The example is based on the Design Editor
, however, it is exactly the same for all the other solutions.
Explore a full code sample on GitHub.
Navigation Bar Architecture
The navigation bar is a list of items placed horizontally at the top of the editor. Every item in the navigation bar conforms to NavigationBar.Item: EditorComponent
where its Context
is constraint to be of type NavigationBar.Context
. NavigationBar.Button
is a provided implementation of the NavigationBar.Item
protocol that has an action and a label. You can also create your own fully custom editor component that allows drawing arbitrary content by conforming your type to NavigationBar.Item
.
Modifiers
After initializing an editor SwiftUI view you can apply any SwiftUI modifier to customize it like for any other SwiftUI view.
All public Swift extension
s of existing types provided by IMG.LY, e.g., for the SwiftUI View
protocol, are exposed in a separate .imgly
property namespace.
The navigation bar configuration to customize the editor is no exception to this rule and is implemented as SwiftUI modifiers.
All navigation bar modifiers and NavigationBar.Item
s provide the NavigationBar.Context
to access the engine, the asset library configuration, the EditorState
, and the EditorEventHandler
that can be used to send UI events.
-
navigationBarItems
- the@NavigationBar.Builder
that registers theNavigationBar.Item
s and defines their order. Note that registering does not mean displaying. The items will be displayed ifNavigationBar.Item.isVisible(_:)
returns true for them. All items need to be enclosed by aNavigationBar.ItemGroup
similar to a regular SwiftUIToolbarItemGroup
which defines the items’ placement. The default implementation of this modifier depends on the used editor solution as each editor provides the most reasonable default behavior for its use case with minimal required code. This example shows the default implementation for the Design Editor. Please see the default navigation bar items below for the defaults of the other solutions. -
modifyNavigationBarItems
- the modifications that should be applied to the order of items defined by the.imgly.navigationBarItems
builder above. This modifier can be used, when you do not want to touch the default general order of the items, but rather add additional items and replace/hide some of the default items. To achieve that, use theNavigationBar.Modifier
provided as the second closure argument, nameditems
in this example, to add, replace, and remove items as highlighted in modify navigation bar items. By default, no modifications are applied.
Default Navigation Bar Items
This example shows the default implementations of the .imgly.navigationBarItems
modifier for each solution. You can overwrite these defaults by using the modifier in your code to define your own set of navigation bar items.
These are the default items recommended to be used with the Design Editor.
These are the default items recommended to be used with the Photo Editor.
These are the default items recommended to be used with the Video Editor.
These are the default items recommended to be used with the Apparel Editor.
These are the default items recommended to be used with the Postcard Editor.
Modify Navigation Bar Items
In this example, we will modify the Design Editor navigation bar items
with the .imgly.modifyNavigationBarItems
modifier. Each modification is only applied to the items defined by .imgly.navigationBarItems
. The operations also accept a @NavigationBar.Builder
so that you can define multiple items in the closures.
-
addFirst
- prepends newNavigationBar.Item
s to anNavigationBar.ItemGroup
defined by theNavigationBar.ItemPlacement
. -
addLast
- appends newNavigationBar.Item
s to anNavigationBar.ItemGroup
defined by theNavigationBar.ItemPlacement
. -
addAfter
- adds newNavigationBar.Item
s right after the item with the provided id. An error will be thrown if no item exists with the provided id. -
addBefore
- adds newNavigationBar.Item
s right before the item with the provided id. An error will be thrown if no item exists with the provided id. -
replace
- replaces theNavigationBar.Item
with the provided id with newNavigationBar.Item
s. An error will be thrown if no item exists with the provided id. The new items don’t need to have the same id as the replaced item. In this example, just the labels of the close editor and export buttons are replaced..labelStyle(.titleAndIcon)
could be applied to theLabel
s to show their titles if you reserved enough space in your navigation bar. -
remove
- removes theNavigationBar.Item
with the provided id. An error will be thrown if no item exists with the provided id.
NavigationBar.Item Configuration
As mentioned in the Navigation Bar Architecture section, NavigationBar.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 NavigationBar.Buttons.
namespace. All available predefined buttons are listed below.
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. This example uses the default values of this particular predefined button.
-
action
- the action to perform when the user triggers the button. In this example, the engine is used to perform an undo step. -
label
- the view that describes the purpose of the button’saction
. Don’t encode the visibility in this view. UseisVisible
instead unless layout space should be reserved in the hidden state like in this example with aLabel
view. -
isEnabled
- whether the button is enabled. In this example, true is only used when an undo step can be performed. -
isVisible
- whether the button should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in thelabel
view unless layout space should be reserved in the hidden state. In this example, true is always used.
Create New Buttons
If our predefined buttons don’t fit your needs you can create your own.
-
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 unless layout space should be reserved in the hidden state. 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 unless layout space should be reserved in the hidden state. 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 NavigationBar.Item
protocol.
-
var id: EditorComponentID { get }
- the unique id of the item. This property is required. -
func body(_: NavigationBar.Context) throws -> some View
- the body of your view. Don’t encode the visibility in this view. UseisVisible
instead unless layout space should be reserved in the hidden state. This property is required. -
func isVisible(_: NavigationBar.Context) throws -> Bool
- whether the item should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in thebody
view unless layout space should be reserved in the hidden state. By default, true is always used.
List of Available NavigationBar.Buttons
This is a comprehensive list of all predefined buttons. Some of them were already used in the previous sections. They are static functions that look like this: NavigationBar.Buttons.{name}
. All these functions return a NavigationBar.Button
. They are public and can be used in your application. Note that all the parameters of these functions have default values, therefore, you do not need to provide any values, however, if you want to modify any of the parameters, it is exactly the same as described in the Customize Predefined Buttons section.
Button | ID | Description |
---|---|---|
NavigationBar.Buttons.closeEditor | NavigationBar.Buttons.ID.closeEditor | Closes editor via editor event .closeEditor . |
NavigationBar.Buttons.undo | NavigationBar.Buttons.ID.undo | Does undo operation in the editor via EditorAPI.undo engine API. |
NavigationBar.Buttons.redo | NavigationBar.Buttons.ID.redo | Does redo operation in the editor via EditorAPI.redo engine API. |
NavigationBar.Buttons.export | NavigationBar.Buttons.ID.export | Triggers onExport callback via editor event .startExport . |
NavigationBar.Buttons.togglePreviewMode | NavigationBar.Buttons.ID.togglePreviewMode | Updates editor view mode via editor event .setViewMode : when current view mode is EditorViewMode.edit , then EditorViewMode.preview is set and vice versa. Note that this button is intended to be used in Photo Editor, Apparel Editor and Postcard Editor and may cause unexpected behaviors when used in other solutions. |
NavigationBar.Buttons.togglePagesMode | NavigationBar.Buttons.ID.togglePagesMode | Updates editor view mode via editor event .setViewMode : when current view mode is EditorViewMode.edit , then EditorViewMode.pages is set and vice versa. Note that this button is intended to be used in Design Editor and may cause unexpected behaviors when used in other solutions. |
NavigationBar.Buttons.previousPage | NavigationBar.Buttons.ID.previousPage | Navigates to the previous page via editor event .navigateToPreviousPage . |
NavigationBar.Buttons.nextPage | NavigationBar.Buttons.ID.nextPage | Navigates to the next page via editor event .navigateToNextPage . |