Token导航 LogoToken导航TokenDH.com
AI 工具只读github未标认证来源可访问clear审计通过

axiom-swiftui-layout公理 Swiftui 布局

Agent Skill

用于辅助界面设计、视觉规范、排版、配色、布局和交互体验优化。它适合让 Agent 根据产品场景整理页面结构、生成 UI 方案、检查视觉一致性或改进组件层级。使用时需要结合现有品牌、设计系统和用户任务,不应只堆装饰元素;涉及真实页面改动时,应通过截图或浏览器预览检查文本溢出、对齐和响应式表现。

总安装

5,304

周安装

221

GitHub Stars

873

下载量

1,768
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:axiom-swiftui-layout(公理 Swiftui 布局)
来源仓库:https://github.com/charleswiltgen/axiom
仓库路径:skills/axiom-swiftui-layout
安装命令:
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-swiftui-layout
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-swiftui-layout

简介

axiom-swiftui-layout 专注于自适应布局设计,确保界面在不同设备和屏幕尺寸下正确响应。

  • 适用于解决 Split View、iPad 分屏或多任务模式下的布局断裂问题。
  • 提供 GeometryReader、ViewThatFits 等工具的选择建议及常见反模式规避策略。
  • 使用时需绑定容器尺寸而非设备假设,保证未来新形态设备的兼容性。
  • 涉及真实布局改动时应通过预览或截图验证文本溢出与对齐表现。

SKILL.md

SwiftUI Adaptive Layout

Overview

Discipline-enforcing skill for building layouts that respond to available space rather than device assumptions. Covers tool selection, size class limitations, iOS 26 free-form windows, and common anti-patterns.

Core principle: Your layout should work correctly if Apple ships a new device tomorrow, or if iPadOS adds a new multitasking mode next year. Respond to your container, not your assumptions about the device.

When to Use This Skill

  • "How do I make this layout work on iPad and iPhone?"
  • "Should I use GeometryReader or ViewThatFits?"
  • "My layout breaks in Split View / Stage Manager"
  • "Size classes aren't giving me what I need"
  • "Designer wants different layout for portrait vs landscape"
  • "Preparing app for iOS 26 window resizing"

Decision Tree

"I need my layout to adapt..."
│
├─ TO AVAILABLE SPACE (container-driven)
│   │
│   ├─ "Pick best-fitting variant"
│   │   → ViewThatFits
│   │
│   ├─ "Animated switch between H↔V"
│   │   → AnyLayout + condition
│   │
│   ├─ "Read size for calculations"
│   │   → onGeometryChange (iOS 16+)
│   │
│   └─ "Custom layout algorithm"
│       → Layout protocol
│
├─ TO PLATFORM TRAITS
│   │
│   ├─ "Compact vs Regular width"
│   │   → horizontalSizeClass (⚠️ iPad limitations)
│   │
│   ├─ "Accessibility text size"
│   │   → dynamicTypeSize.isAccessibilitySize
│   │
│   └─ "Platform differences"
│       → #if os() / Environment
│
└─ TO WINDOW SHAPE (aspect ratio)
    │
    ├─ "Portrait vs Landscape semantics"
    │   → Geometry + custom threshold
    │
    ├─ "Auto show/hide columns"
    │   → NavigationSplitView (automatic in iOS 26)
    │
    └─ "Window lifecycle"
        → @Environment(\.scenePhase)

Tool Selection

Quick Decision

Do you need a calculated value (width, height)?
├─ YES → onGeometryChange
└─ NO → Do you need animated transitions?
         ├─ YES → AnyLayout + condition
         └─ NO → ViewThatFits

When to Use Each Tool

I need to...Use thisNot this
Pick between 2-3 layout variantsViewThatFitsif size > X
Switch H↔V with animationAnyLayoutConditional HStack/VStack
Read container sizeonGeometryChangeGeometryReader
Adapt to accessibility textdynamicTypeSizeFixed breakpoints
Detect compact widthhorizontalSizeClassUIDevice.idiom
Detect narrow window on iPadGeometry + thresholdSize class alone
Hide/show sidebarNavigationSplitViewManual column logic
Custom layout algorithmLayout protocolNested GeometryReaders

Pattern 1: ViewThatFits

Use when: You have 2-3 layout variants and want SwiftUI to pick the first that fits.

ViewThatFits {
    // First choice: horizontal
    HStack {
        Image(systemName: "star")
        Text("Favorite")
        Spacer()
        Button("Add") { }
    }

    // Fallback: vertical
    VStack {
        HStack {
            Image(systemName: "star")
            Text("Favorite")
        }
        Button("Add") { }
    }
}

Limitation: ViewThatFits doesn't expose which variant was chosen. If you need that state for other views, use AnyLayout instead.


Pattern 2: AnyLayout for Animated Switching

Use when: You need animated transitions between layouts, or need to know current layout state.

struct AdaptiveStack<Content: View>: View {
    @Environment(\.horizontalSizeClass) var sizeClass

    let content: Content

    var layout: AnyLayout {
        sizeClass == .compact
            ? AnyLayout(VStackLayout(spacing: 12))
            : AnyLayout(HStackLayout(spacing: 20))
    }

    var body: some View {
        layout {
            content
        }
        .animation(.default, value: sizeClass)
    }
}

For Dynamic Type:

@Environment(\.dynamicTypeSize) var dynamicTypeSize

var layout: AnyLayout {
    dynamicTypeSize.isAccessibilitySize
        ? AnyLayout(VStackLayout())
        : AnyLayout(HStackLayout())
}

Pattern 3: onGeometryChange (Preferred for Geometry)

Use when: You need actual dimensions for calculations. Preferred over GeometryReader.

struct ResponsiveGrid: View {
    @State private var columnCount = 2

    var body: some View {
        LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: columnCount)) {
            ForEach(items) { item in
                ItemView(item: item)
            }
        }
        .onGeometryChange(for: Int.self) { proxy in
            max(1, Int(proxy.size.width / 150))
        } action: { newCount in
            columnCount = newCount
        }
    }
}

For aspect ratio detection (iPad "orientation"):

struct WindowShapeReader: View {
    @State private var isWide = true

    var body: some View {
        content
            .onGeometryChange(for: Bool.self) { proxy in
                proxy.size.width > proxy.size.height * 1.2
            } action: { newValue in
                isWide = newValue
            }
    }
}

Pattern 4: GeometryReader (When Necessary)

Use when: You need geometry AND are on iOS 15 or earlier, OR need geometry during layout phase (not just as side effect).

// ✅ CORRECT: Constrained GeometryReader
VStack {
    GeometryReader { geo in
        Text("Width: \(geo.size.width)")
    }
    .frame(height: 44)  // MUST constrain!

    Button("Next") { }
}

// ❌ WRONG: Unconstrained (greedy)
VStack {
    GeometryReader { geo in
        Text("Width: \(geo.size.width)")
    }
    // Takes all available space, crushes siblings
    Button("Next") { }
}

Size Class Truth Table (iPad)

ConfigurationHorizontalVertical
Full screen portrait.regular.regular
Full screen landscape.regular.regular
70% Split View.regular.regular
50% Split View.regular.regular
33% Split View.compact.regular
Slide Over.compact.regular
With keyboard(unchanged)(unchanged)

Key insight: Size class only goes .compact on iPad at ~33% width or Slide Over. For finer control, use geometry.


iOS 26 Free-Form Windows

What Changed

Before iOS 26iOS 26+
Fixed Split View sizesFree-form drag-to-resize
UIRequiresFullScreen allowedDeprecated
No menu bar on iPadMenu bar via .commands
Manual column visibilityNavigationSplitView auto-adapts

Apple's Guideline

"Resizing an app should not permanently alter its layout. Be opportunistic about reverting back to the starting state whenever possible."

Translation: Don't save layout state based on window size. When window returns to original size, layout should too.

NavigationSplitView Auto-Adaptation

// iOS 26: Columns automatically show/hide
NavigationSplitView {
    Sidebar()
} content: {
    ContentList()
} detail: {
    DetailView()
}
// No manual columnVisibility management needed

Migration Checklist

  • Remove UIRequiresFullScreen from Info.plist
  • Test at arbitrary window sizes (not just 33/50/66%)
  • Verify layout doesn't "stick" after resize
  • Add menu bar commands for common actions
  • Test Window Controls don't overlap toolbar items

Anti-Patterns

❌ Device Orientation Observer

// ❌ WRONG: Reports device, not window
NotificationCenter.default.addObserver(
    forName: UIDevice.orientationDidChangeNotification, ...
)

let orientation = UIDevice.current.orientation
if orientation.isLandscape { ... }

Why it fails: Reports physical device orientation, not window shape. Wrong in Split View, Stage Manager, iOS 26.

Fix: Use onGeometryChange to read actual window dimensions.

❌ Screen Bounds

// ❌ WRONG: Returns full screen, not your window
let width = UIScreen.main.bounds.width
if width > 700 { useWideLayout() }

Why it fails: In multitasking, your app may only have 40% of the screen.

Fix: Read your view's actual container size.

❌ Device Model Checks

// ❌ WRONG: Breaks on new devices, wrong in multitasking
if UIDevice.current.userInterfaceIdiom == .pad {
    useWideLayout()
}

Why it fails: iPad in 1/3 Split View is narrower than iPhone 14 Pro Max landscape.

Fix: Respond to available space, not device identity.

❌ Unconstrained GeometryReader

// ❌ WRONG: GeometryReader is greedy
VStack {
    GeometryReader { geo in
        Text("Size: \(geo.size)")
    }
    Button("Next") { }  // Crushed
}

Fix: Constrain with .frame() or use onGeometryChange.

❌ Size Class as Orientation Proxy

// ❌ WRONG: iPad is .regular in both orientations
var isLandscape: Bool {
    horizontalSizeClass == .regular  // Always true on iPad!
}

Fix: Calculate from actual geometry if you need aspect ratio.


Pressure Scenarios

"Designer wants iPhone-specific layout"

Temptation: if UIDevice.current.userInterfaceIdiom ==.phone

Response: "I'll implement these as 'compact' and 'regular' layouts that switch based on available space. The iPhone layout will appear on iPad when the window is narrow. This future-proofs us for Stage Manager and iOS 26."

"Just use GeometryReader, it's fine"

Temptation: Wrap everything in GeometryReader.

Response: "GeometryReader has known layout side effects — it expands greedily. onGeometryChange reads the same data without affecting layout. It's backported to iOS 16."

"Size classes worked before"

Temptation: Force everything through size class.

Response: "Size classes are coarse. iPad is .regular in both orientations. I'll use size class for broad categories and geometry for precise thresholds."

"We don't support iPad multitasking"

Temptation: UIRequiresFullScreen = true

Response: "Apple deprecated full-screen-only in iOS 26. Even without active Split View support, the app can't break when resized. Space-based layout costs the same."


Resources

WWDC: 2025-208, 2024-10074, 2022-10056

Skills: axiom-swiftui-layout-ref, axiom-swiftui-debugging, axiom-liquid-glass

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

28.04%
按下载量换算496

Codex

21.76%
按下载量换算385

OpenCode

17.21%
按下载量换算304

Antigravity

12.8%
按下载量换算226

Cursor

7.74%
按下载量换算137

Gemini CLI

3.6%
按下载量换算64

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills