UIGeek: A Structure for Native iOS App Development

I'm excited to introduce UIGeek, a structured approach and toolkit for building native iOS apps. It started as the rough prototype I wrote about earlier, and it's now a proper framework that anyone can use.

The best way to explain what it does is to show you. Every screen, transition, and interaction in this case study was built with UIGeek. In fact, so was the entire sample app and its supporting documentation, from the navigation architecture and shared components to every polished demo. I'd describe what I wanted, watch what the structure produced, identify the parts that still felt off, and feed the refinements back in. UIGeek helped build UIGeek.

The UIGeek desktop app: a reasoning panel on the left reads the existing project files and plans the app's models and views, while an iPhone preview on the right shows the resulting habit tracker.
A faux example of UIGeek in action: a clean native dashboard with proper safe-area handling, system fonts, and fluid navigation, generated and refined through the structure.
The UIGeek start screen: a green speech-bubble mark above the question 'What should we build today?'
The light-mode start state: one prompt field, nothing to configure first.

What follows is a tour of UIGeek's core pieces. Every demo was made with the feature it's showing. Yes, it's very meta.


Why native iOS feels hard

Building a native iOS app is so hard. You juggle UIKit or SwiftUI, Auto Layout or the new layout system, state management, navigation stacks, accessibility, Dark Mode, Dynamic Type, device-specific quirks, App Store requirements, and the constant feeling that something is one constraint away from breaking. That's why we built the UIGeek app development structure: a deliberate set of conventions, reusable primitives, and feedback loops that remove the friction without sacrificing the polish of true native code.

The loop looked like this: the structure generates a solid starting screen or flow. I run it on device or simulator, interact with it a few times. Something feels off. Maybe the spacing doesn't match Human Interface Guidelines, a transition is too abrupt, or a list doesn't respect safe areas properly. I note the issue against the exact component or layout rule, feed it back, and the structure adjusts. I check again. Still not quite right. Another pass.

This went on for hours. Dozens of iterations per screen. Hundreds across the entire sample app and docs.

A dark UIGeek window asking 'What app do you want to build?' above a row of four platform targets: phone, desktop display, laptop and watch.
Pick the target first (phone, desktop, laptop or watch) before a single line of layout is written.

Text and content refinement

The simplest case is copy and labels. You see a string that's too long for the button, or a title that doesn't match the system style. You select it, note the fix, and the structure updates the localized string and styling in one go. I cleaned up dozens of copy and Dynamic Type issues this way.

Select text or labels to annotate content, localization, or typography problems.

The composer holding a typed instruction above four attached reference thumbnails.
The composer takes a written instruction alongside reference images, so content and its source material arrive together.

Component and view targeting

For everything else, you point at the view. UIGeek captures enough context (view hierarchy, modifiers, constraints or layout priorities, trait collections) for the next iteration to land precisely. Most of the screens you're imagining were refined this way: identify, note, iterate.

Tap any view or control to add structured feedback.

Typing an @ symbol in the composer opens a capability menu.
Typing @ scopes the request: Documents, Presentations, Computer, or Build iOS Apps for SwiftUI and App Intents work.

Multi-view and layout selection

Sometimes you need to adjust several related elements at once. I used this constantly when aligning navigation items, list cells, or toolbar buttons that all needed the same treatment.

Select multiple views to apply consistent spacing, styling, or behavior changes.


Region and empty-space feedback

You can also target empty regions. I used this for layout feedback, pointing at gaps that felt too tight, or areas where a secondary action should appear without breaking the visual hierarchy.

Drag to select any region, including empty space, for layout notes.


Animation and state freeze

SwiftUI and UIKit animations are the trickiest. The exact intermediate state you want to improve might only exist for a fraction of a second. The structure's inspection tools let you pause or scrub so you can note the precise timing, spring parameters, or matchedGeometry effect that needs work.

Freeze or scrub animations to annotate specific frames and transitions.


What the feedback captures

When you target a view, the output includes its identity (type, accessibility identifier, or key path), position in the hierarchy, frame, and relevant traits. When you select text, you get the exact string. Views are identified by the most useful signal: label text, accessibility label, or structural role. "Make the avatar smaller" is ambiguous. Image with a specific accessibility identifier or the exact modifier chain is not. This precision is why the feedback loop stayed tight even after hundreds of iterations.


Calibrating the detail

How much context you need depends on the problem. Fixing a label? The structure just needs the string and its location. Debugging why a sheet transition feels wrong? That may need the full presentation style, detents, animation curve, and surrounding environment values.

So there are graduated levels of output: Compact (identity + note), Standard (adds frame and key modifiers), Detailed (hierarchy and nearby context), and Forensic (computed traits, environment, and layout priorities). Most of the time Standard was enough. When the settings panel animation still felt off, switching to Forensic showed exactly which values were being applied. The next pass fixed it cleanly.


Now available

UIGeek is a structured set of conventions, starter templates, and inspection helpers for native iOS. Add the core modules to your project, follow the layout and component patterns, and the refinement loop becomes straightforward. It works with pure SwiftUI, UIKit, or mixed codebases.

Swift

// Example integration sketch
import UIGeek

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .uiGeekEnvironment() // enables structured inspection & conventions in debug
        }
    }
}
An 'Upgrade to plus' dialog comparing two plans.
Plans and credits: a free tier for building, testing and exporting, and a Plus tier adding rollover credits, priority support, and TestFlight and App Store distribution.

People talk about one-shotting: getting a perfect native screen on the first try. UIGeek is less about that and more about giving yourself (and any AI or teammate helping you) what is needed to make each pass count. Sometimes that's one pass. Usually it's a few. The point is every pass moves the app meaningfully closer to feeling native and finished. This is still a v1. But even in its current form, it has already changed how I approach native iOS work. Hopefully it does the same for you. To learn more, check out the full UIGeek documentation and sample project.

Documentation Sample project

Acknowledgements

Special thanks to the collaborators who helped shape the early patterns and feedback tools. This case study was designed and iterated with the help of… you guessed it, the same structure.