What you get
One SwiftUI view file. Every view is placed with .position(x:, y:) computed from the coordinates you drew, so the layout is not re-derived on the way into Xcode.
import SwiftUI
struct Reminders: View {
@State private var field3: String = ""
@State private var field3Height: CGFloat = 96
var body: some View {
ScrollView(showsIndicators: false) {
ZStack(alignment: .topLeading) {
Color(red: 1, green: 1, blue: 1)
.frame(width: 390, height: 844 + (max(0, field3Height - 96)))
Text("Reminders")
.font(.custom("Inter", size: 22))
.fontWeight(.bold)
.lineSpacing(6.6)
.foregroundColor(Color(red: 0.09, green: 0.09, blue: 0.1))
.multilineTextAlignment(.leading)
.frame(width: 200, height: 28, alignment: .topLeading)
.position(x: 124, y: 78)
RoundedRectangle(cornerRadius: 16)
.fill(Color(red: 0.16, green: 0.31, blue: 0.85))
.frame(width: 220, height: 96)
.position(x: 134, y: 160)
ZStack(alignment: .topLeading) {
Text(field3.isEmpty ? " " : field3)
.font(.custom("Inter", size: 16))
.padding(EdgeInsets(top: 10, leading: 12, bottom: 10, trailing: 12))
.frame(width: 280, alignment: .topLeading)
.fixedSize(horizontal: false, vertical: true)
.opacity(0)
.background(GeometryReader { geo in Color.clear.preference(key: GrowHeightKey.self, value: geo.size.height) })
TextEditor(text: $field3)
.font(.custom("Inter", size: 16))
.foregroundColor(Color(red: 0.09, green: 0.09, blue: 0.1))
.multilineTextAlignment(.leading)
.scrollDisabled(true)
.padding(EdgeInsets(top: 10, leading: 12, bottom: 10, trailing: 12))
}
.onPreferenceChange(GrowHeightKey.self) { field3Height = $0 }
.frame(width: 280, height: max(96, field3Height))
.background(Color(red: 1, green: 1, blue: 1))
.cornerRadius(12)
.overlay(RoundedRectangle(cornerRadius: 12).strokeBorder(Color(red: 0.89, green: 0.88, blue: 0.85), lineWidth: 1))
.position(x: 164, y: 232 + (0) + max(96, field3Height) / 2)
}
.frame(width: 390, height: 844 + (max(0, field3Height - 96)))
}
.frame(width: 390, height: 844)
}
}
private struct GrowHeightKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = max(value, nextValue())
}
}It compiles, and we check
Generated SwiftUI is type-checked against the real iOS SDK using swiftc -typecheck, via a dedicated verification suite (npm run verify:native) that runs outside the fast test suite because it needs Xcode installed. This is worth stating plainly because "looks like SwiftUI" and "compiles as SwiftUI" are different claims, and only one of them saves you time.
Which devices offer it
SwiftUI appears for Apple targets only: iPhone, iPad, macOS, and watchOS presets, plus generic artboards. It is never offered for Android or Windows screens.
watchOS is the one platform where SwiftUI is the only target available, for the obvious reason.
What it handles
Placement. .position(x:, y:) from your exact canvas coordinates.
Multiline inputs that grow. A multiline field renders as a TextEditor that measures its own wrapped text and grows to fit, pushing later content down. This is the behavior a fixed .frame would clip, and matching the canvas here took more work than anything else in the generator.
Scrolling. The screen wraps in a ScrollView sized to the full content height when content exceeds the device, and also whenever the design contains a multiline field, even if everything currently fits. A field that grows at runtime would otherwise push content somewhere the user cannot reach.
What it does not handle
- No responsive layout, and specifically no size classes. iPhone and iPad are two screens here, not one adaptive layout.
- No horizontal scrolling.
Working with the output
Plain SwiftUI, straight into Xcode. There is no package to add and no dependency on us.
You may notice a GrowHeightKey PreferenceKey struct in the output. It is emitted only when the design contains a multiline field, and it is how the growing field reports its measured height back up. Without a multiline field it does not appear. View names come from your canvas layer names, camelCased; unnamed shapes become shape1, shape2, and so on.
Because placement is absolute, the generated view is a faithful screen rather than a set of reusable components. If you are building a design system, treat the export as the specification of what a screen should look like and lift pieces out of it, rather than expecting idiomatic composed views.