◉RORK LABJP
●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●SDK 58 — SDK 58 Beta has been out since Sep 15. The stable date is still unconfirmed●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 3 days left●Q&A — People are asking why expo-widgets render blank only in production builds●RORK — GPT-6.1 Sol was added on Sep 29, available on Pro and Max plans●NEW — Building an app for a client? Decide who owns the publishing account first●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●SDK 58 — SDK 58 Beta has been out since Sep 15. The stable date is still unconfirmed●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 3 days left●Q&A — People are asking why expo-widgets render blank only in production builds●RORK — GPT-6.1 Sol was added on Sep 29, available on Pro and Max plans●NEW — Building an app for a client? Decide who owns the publishing account first
Articles/Dev Tools
⬡ Dev Tools/2026-06-30Advanced

Building StandBy-Optimized Widgets in Rork Max

A hands-on walkthrough for tuning WidgetKit widgets for StandBy mode, the landscape charging display in iOS 17+. Covers always-on dimming, night mode, and container backgrounds, including which parts of Rork Max's generated code you still have to finish by hand.

Rork Max235WidgetKit11StandBySwiftUI66iOS115

✦ Premium Article

Place a charging iPhone on its side at your bedside and the screen fills with a large clock and a row of widgets. That is StandBy, introduced in iOS 17. The other day I was rebuilding the widget for one of my own apps as an indie developer, "Law of Attraction Everyday," in Rork Max. It looked fine on the Home Screen, but the moment I dropped it into StandBy the text clipped, and under the dim red night display I couldn't read what it said at all.

StandBy is not simply a "show the widget bigger" mode. You are suddenly dealing with three different environments at once: dimming on the always-on display, the deep-night red mode, and a landscape-only layout. Rork Max builds the WidgetKit scaffolding from a plain-language prompt, but the part that bridges those three environments is something I had to read the generated code and finish myself. Here is what I learned, written up as an implementation sequence.

When StandBy activates, and what changes

As a starting point, StandBy only activates when all three of these are true at the same time.

  1. The iPhone is charging (MagSafe, Lightning, or USB-C all qualify)
  2. It is held in landscape orientation
  3. It is locked

This combination is easy to overlook during development, and the simulator does not reproduce it reliably. I burned time trying to verify it in the simulator at first. It is safer to assume that the only dependable way to check StandBy behavior is to charge a real device in landscape.

StandBy widgets reuse the Home Screen's systemSmall family directly. Rather than adding a new widget family, your existing small widget lines up in the StandBy stack. What matters here is branching the presentation by environment values.

EnvironmentEnvironment value to readWhat it needs
Normal Home ScreendefaultFull color, normal information density
StandBy, daytimewidgetRenderingMode = fullColorMore padding, larger text
StandBy night modeisLuminanceReduced = trueRed monochrome, minimal elements, less lit area
Always-on (14 Pro and later)isLuminanceReduced = true1Hz refresh assumed, animation suppressed

Night mode and the always-on display are both caught by isLuminanceReduced, but the intent differs slightly. The former is about not being glaring in a dark room; the latter is about limiting burn-in and power draw. In code, you can satisfy both by pushing in the same direction: reduce the lit area and stop motion.

Step 1: Always declare a container background

Since iOS 17, if a widget does not declare its background with containerBackground(for: .widget), you get cases in StandBy and on the Lock Screen where the background drops out and the text floats alone, or the layout collapses. In the code Rork Max generated, this declaration showed up as a hand-rolled background inside a ZStack, and that form broke in StandBy.

struct AffirmationWidgetView: View {
    var entry: AffirmationEntry
 
    var body: some View {
        VStack(alignment: .leading, spacing: 6) {
            Text(entry.affirmation)
                .font(.headline)
                .minimumScaleFactor(0.6)   // allow shrink so it doesn't clip in StandBy
                .lineLimit(3)
            Spacer(minLength: 0)
            Text(entry.date, style: .time)
                .font(.caption2)
                .foregroundStyle(.secondary)
        }
        // ❌ A hand-rolled background alone peels off in StandBy
        // .background(Color.indigo)
 
        // ✅ Let the system recognize it as a container background
        .containerBackground(for: .widget) {
            Color.indigo
        }
    }
}

I add minimumScaleFactor because in StandBy the effective drawing area of the same systemSmall expands, which makes a fixed font look relatively small. Leave the font size fixed and a long affirmation clips mid-sentence. This is a textbook case of something that causes no trouble on the Home Screen and only surfaces in StandBy.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You'll be able to take a widget that looked broken in StandBy and make it hold up in both always-on and full-color states
✦You'll get working code for dimming-aware rendering using isLuminanceReduced and rendering modes
✦You'll learn exactly which parts of Rork Max's generated WidgetKit code you need to finish yourself
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

Related Articles

⬡ Dev Tools2026-04-05
Rork Max × WidgetKit & Live Activities in Practice — From Home Screen to Dynamic Island
A complete guide to implementing iOS Widgets, Lock Screen widgets, and Dynamic Island Live Activities with Rork Max. Covers WidgetKit fundamentals, Timeline update strategies, App Intents integration, and monetization.
⬡ Dev Tools2026-09-05
Your Widget Extension Can Submit a BGTaskScheduler Request. It Just Cannot Register the Handler
Calling BGTaskScheduler from a widget extension compiles, submits, and returns true — and then nothing runs. Here is why registration belongs to the host app only, and how I moved refresh ownership back where it belongs across my wallpaper apps.
⬡ Dev Tools2026-07-18
The Generated Screen That Quietly Jams at AX5 and in German — Putting Layout Resilience Checks on Rork Max SwiftUI
A record of running every Rork Max generated SwiftUI screen through pseudolocalization and the largest text size to find exactly where it jams. Covers when to reach for ViewThatFits, ScaledMetric and layoutPriority, plus the snapshot checks that catch regressions every time you regenerate.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links