Your page looks great on desktop. You switch to the Android emulator and the header is jammed under the status bar. The fix is almost always one line. But you just spent 25 minutes figuring out which element needs it, on which target, because you were working from impressions instead of evidence.
You know what happens next. You eyeball it. You guess it's a padding issue on the header. You hardcode a margin, rebuild, wait for the emulator, and check. Wrong element. Try again. Rebuild. Wait. Check. Closer, but now there's extra space on desktop.
There's a version of this workflow where you skip the guessing entirely.
The Fix Is Easy. Finding the Problem Is the Problem.
Uno Platform's App MCP connects your AI assistant to the running app. Not to the source code, to the actual rendered UI. It reads the live visual tree: margins, padding, bounds, position. Real values from real elements on the real target.
That changes the debugging question from "what do I think is wrong?" to "what do the numbers say?"
The Walkthrough
A ProfilePage with a header area. Looks correct on desktop. On Android, the header overlaps the status bar.
1 Capture the Baseline on Desktop
Run the app on desktop. Ask the assistant to inspect the ProfilePage header: margins, padding, rendered bounds of the top-level Grid and its first children.
The result: header Grid starts at Y=32. Correct inset below the title bar.
That's your baseline. Save it.
2 Inspect on Android
Same app, same page, Android target. Same inspection.
Header Grid starts at Y=0.
That's it. That's the diagnosis. The header doesn't account for the status bar. No guessing. No "I think it might be the padding." Y=32 on desktop, Y=0 on Android.
3 Get the Right Fix
Now you bring in the Uno MCP (the documentation server) with the evidence:
"The header Grid starts at Y=0 on Android. On desktop it's Y=32. What's the recommended way to handle safe area insets?"
The answer:
<Grid utu:SafeArea.Insets="Top">
<!-- header content -->
</Grid>
One attribute. On Android, it adds the status bar offset. On desktop, it adds nothing. Platform-aware behavior, no conditional logic, no hardcoded values.
4 Verify on Android
Apply. Rebuild. Run on Android.
Inspect the header again. It now starts at Y=48 (Android's status bar height). No overlap.
5 Cross-Check Desktop. Don't Skip This.
This is the step everyone skips, and it's the one that matters most.
Switch back to desktop. Run. Inspect the header.
Y=32. Identical to the baseline.
The SafeArea attribute correctly does nothing where there's no inset. Your fix didn't regress the target that was already working.
If you'd hardcoded Margin="0,48,0,0" instead, this is where you'd discover it pushed the desktop header down by 16px. Your eyes might call that "close enough." Y=32 vs Y=48 would not.
Why This Matters More Than the Fix
You probably could have guessed SafeArea.Insets="Top". That's not the point.
The point is that without runtime inspection, you might have hardcoded a margin that fixes Android and breaks desktop. Or applied SafeArea to the page instead of the header, which shifts child layout in ways you won't notice until three sprints later. Or you might have gotten it right on the first guess and then had no way to prove it didn't introduce a subtle regression on your other targets.
The visual tree gives you numbers. Numbers don't lie and they don't look "close enough."
Common Cross-Platform Layout Pitfalls
| Symptom | Likely Cause | Diagnostic |
|---|---|---|
| Content under status bar on Android | Missing SafeArea | Check header Y-position in visual tree |
| Extra space at top on iOS | SafeArea applied to wrong element | Compare bounds of header vs page |
| Different spacing on desktop vs mobile | Hardcoded margins instead of SafeArea | Compare Margin/Padding values across targets |
| Content clipped at bottom on mobile | Not accounting for navigation bar | Check bottom bounds in visual tree |
| Touch targets wrong despite correct layout | Element bounds smaller than visual | Inspect ActualWidth/ActualHeight vs visible area |
The Pattern
For any layout change targeting a platform-specific issue:
- Capture baseline on your primary target. Actual values, not a screenshot you eyeball.
- Inspect the broken target. Get exact numbers for the discrepancy.
- Propose a platform-aware fix using Uno Platform docs, not a hardcoded workaround.
- Verify the fix on the affected target.
- Re-verify the baseline on every other target.
Step 5 is the whole point. A fix that works on one target and silently regresses another isn't a fix. It's a time bomb with a longer fuse.
Subscribe to Our Blog
Subscribe via RSS
Back to Top