Search Docs
Loading...
Skip to content

T-Shirt Designer in iOS

Build print-ready t-shirt designs with a focused mobile UI. Runs entirely on the mobile device with no server dependencies.

T-Shirt Designer starter kit screenshot

10 mins
estimated time
Download
GitHub

Pre-Requisites#

This guide assumes basic familiarity with iOS and Swift. You will need:

  • Latest Xcode
  • Swift 5.9 or later
  • iOS 16.0+

Get Started#

Start with a complete, runnable iOS starter kit project.

Step 1: Clone the Repository#

Terminal window
git clone -b v1.73.0 https://github.com/imgly/starterkit-apparel-editor-ios.git
cd starterkit-apparel-editor-ios

Step 2: Open and Run#

Open the project in Xcode and run on a simulator or connected device:

  1. Open starterkit-apparel-editor-ios.xcodeproj in Xcode
  2. Select your target device or simulator
  3. Press ⌘R to build and run

The sample app shows a “Launch Editor” button. Tapping it presents the apparel editor:

var body: some View {
Editor(settings)
.imgly.configuration {
ApparelEditorConfiguration()
}
}

The full implementation of the starter kit lives in the starter-kit/ folder:

starter-kit/
├── ApparelEditorStarterKit.swift # SwiftUI view that launches the editor
├── ApparelEditorConfiguration.swift # Editor configuration (callbacks + UI components)
├── callbacks/
│ ├── OnCreate+Apparel.swift # Editor initialization logic (outline setup)
│ ├── OnExport+Apparel.swift # Export flow and handling (PDF)
│ └── OnChanged+Apparel.swift # Gesture, page, and view mode handling
└── components/
├── CanvasMenu+Apparel.swift # Canvas menu configuration
├── Dock+Apparel.swift # Dock configuration
├── InspectorBar+Apparel.swift # Inspector bar configuration
└── NavigationBar+Apparel.swift # Navigation bar configuration

Configuring the Starter Kit#

The starter kit provides a generic structure and behavior that you can customize to match your needs. Since the implementation is part of your codebase, you can add, remove, or modify functionality as you wish.

The entry point is ApparelEditorStarterKit.swift, which creates the Editor view and applies the configuration:

Editor(settings)
.imgly.configuration {
ApparelEditorConfiguration()
}

You can configure the editor based on your business logic — for example, loading a scene from a previous editing session or displaying different UI for different users. Add properties to ApparelEditorStarterKit and use them in the .imgly.onCreate callback to customize scene loading or other behavior.

Set Up a Scene#

The scene setup logic is located in OnCreate+Apparel.swift as part of the defaultCreateScene callback:

let sceneURL = Bundle(for: ApparelEditorConfiguration.self).url(
forResource: "apparel-ui-b-empty",
withExtension: "scene",
)!
try await engine.scene.load(from: sceneURL)

CE.SDK offers multiple ways to load a scene into the editor — from a template archive, a blank canvas, or a .scene file.

Customize Assets#

The asset source setup is located in OnCreate+Apparel.swift as part of the defaultLoadAssetSources callback. Enable or disable individual sources:

let assetSources: [String: URL] = [
Engine.DefaultAssetSource.sticker.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.vectorPath.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.filterLut.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.filterDuotone.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.colorsDefaultPalette.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.effect.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.blur.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.typeface.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.cropPresets.rawValue: Engine.assetBaseURL,
Engine.DefaultAssetSource.pagePresets.rawValue: Engine.assetBaseURL,
Engine.DemoAssetSource.image.rawValue: Engine.assetBaseURL,
Engine.DemoAssetSource.textComponents.rawValue: Engine.assetBaseURL,
]
try await withThrowingTaskGroup(of: Void.self) { group in
for assetSource in assetSources {
group.addTask {
try await engine.populateAssetSource(id: assetSource.key, baseURL: assetSource.value)
}
}
try await group.waitForAll()
}
try engine.asset.addLocalSource(
sourceID: Engine.DemoAssetSource.imageUpload.rawValue,
supportedMimeTypes: Engine.DemoAssetSource.imageUpload.mimeTypes,
)
try await engine.asset.addSource(TextAssetSource(engine: engine))
try engine.asset.addSource(PhotoRollAssetSource(engine: engine))

For production deployments, self-hosting assets is required—the IMG.LY CDN is intended for development only. See Serve Assets for downloading assets, configuring baseURL and excluding unused sources to optimize load times.

Customize Export Functionality#

Export handling logic is located in OnExport+Apparel.swift as part of the onExport callback.

The default implementation exports the scene as PDF and opens the system share sheet:

guard let scene = try engine.scene.get() else {
throw EditorError("No scene was found.")
}
let data = try await engine.block.export(scene, mimeType: .pdf) { engine in
try engine.scene.getPages().forEach {
try engine.block.setScopeEnabled($0, key: "layer/visibility", enabled: true)
try engine.block.setVisible($0, visible: true)
}
}
let url = FileManager.default.temporaryDirectory.appendingPathComponent("Export", conformingTo: .pdf)
try data.write(to: url, options: [.atomic])
eventHandler.send(.shareFile(url))

Customize (Optional)#

Base URL#

The starter kit uses Engine.assetBaseURL by default, which points to https://cdn.img.ly/packages/imgly/cesdk-engine/1.73.0/assets. To self-host assets, download the asset zip file and pass a custom baseURL to your EngineSettings.

Color Scheme#

CE.SDK supports light and dark modes out of the box, plus automatic system preference detection. Apply SwiftUI’s .preferredColorScheme modifier to the Editor view to switch themes.

See Theming for more details.

Localization#

See Localization for supported languages, adding support for new languages, and replacing existing keys.

UI Layout#

All configurable components are located in the components/ folder:

  • CanvasMenu+Apparel.swift — see Canvas Menu for full configuration options
  • Dock+Apparel.swift — see Dock for full configuration options
  • InspectorBar+Apparel.swift — see Inspector Bar for full configuration options
  • NavigationBar+Apparel.swift — see Navigation Bar for full configuration options

Troubleshooting#

Editor doesn’t load#

  • Check onCreate: Ensure the onCreate callback loads a scene successfully
  • Verify the baseURL: Assets must be accessible from the CDN or your self-hosted location
  • Check Xcode console: Look for errors in the Xcode debug console

Assets don’t appear#

  • Check network requests: Make sure the device or simulator is connected to the internet
  • Self-host assets for production: See Serve Assets to host assets on your infrastructure
  • Check Xcode console: Look for errors in the Xcode debug console

Export fails or produces blank documents#

  • Wait for content to load: Ensure all elements are fully loaded before exporting
  • Check Xcode console: Look for errors in the Xcode debug console

Watermark appears in production#

  • Add your license key: Set the license property in your EngineSettings
  • Sign up for a trial: Get a free trial license at img.ly/forms/free-trial

Next Steps#