[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f13rxa7lj2no1y":3},{"_id":4,"slug":5,"title":6,"subtitle":7,"kind":8,"cards":9,"tags":37,"categories":38,"source":39,"lang":42,"author":43,"audioState":46,"stats":47,"publishedAt":50,"renderer":51},"6ab9e1d1ca21c797c7e97297","macos27-ios-app-5fcd756b","macOS27 上可变界面尺寸 iOS App 揭秘","把一个 iOS App 放到 Mac 上运行，拖动窗口边缘，变的只有宽高吗？","news",[10,12,17,22,27,32],{"headline":6,"body":7,"imageUrl":11,"sourceImageUrl":11},"https:\u002F\u002Fp3-xtjj-sign.byteimg.com\u002Ftos-cn-i-73owjymdk6\u002F041e9351038c4480ae89aee12462e8d8~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5aSn54aK54yr5L6v5L2p:q75.awebp?rk3s=f64ab15b&x-expires=1790992474&x-signature=Z3m3RmMaWnPVSxQ0v4TxQJcKHGU%3D",{"headline":13,"body":14,"imageUrl":15,"images":16},"在 macOS 27 上做了一次小实验，答案颇有意味：随着用户调整窗口大小，SwiftUI 环境中的 Size Class…","在 macOS 27 上做了一次小实验，答案颇有意味：随着用户调整窗口大小，SwiftUI 环境中的 Size Class 也会发生变化。原本常在横竖屏适配中见到的 compact 和 regular，如今在鼠标拖动之间，有了更直观的表现。 这件事值得留意。对于沿用固定设备假设的界面，一次再普通不过的窗口缩放，就可能让布局捉襟见肘。 说起 Size Class，许多开发者会条件反射地想到“iPhone 用 compact，iPad 用 regular”。这套经验便于入门，却容易先入为主。 SwiftUI 通过两个环境值描述水平和垂直方向的空间分类：","\u002Fapi\u002Fmedia\u002Fposts\u002Fmacos27-ios-app-5fcd756b\u002F1.webp",{"local":15},{"headline":18,"body":19,"imageUrl":20,"images":21},"两者的取值可以是 .compact、.regular，也可能为 nil。水平对应宽度，垂直对应高度。它们描述的是视图所处的布局环境，不能简单当成设备型号的别名。…","两者的取值可以是 .compact、.regular，也可能为 nil。水平对应宽度，垂直对应高度。它们描述的是视图所处的布局环境，不能简单当成设备型号的别名。相关定义可见 Apple 的 UserInterfaceSizeClass 文档。 因此，看见一个宽窗口，便断言两个方向都是 regular，难免以偏概全。窗口的宽与高是两回事，两个方向的分类也应分别观察。 这次实验的做法很直接：让界面同时显示实际可用尺寸与两个 Size Class，然后拖动窗口，观察数值。核心代码并不复杂：","\u002Fapi\u002Fmedia\u002Fposts\u002Fmacos27-ios-app-5fcd756b\u002F2.webp",{"local":20},{"headline":23,"body":24,"imageUrl":25,"images":26},"这里有个细节不能张冠李戴：GeometryReader 测量的是当前视图获得的布局空间，单位为点；它既不是显示器分辨率，也不是包含标题栏的窗口外框尺寸。将它与…","这里有个细节不能张冠李戴：GeometryReader 测量的是当前视图获得的布局空间，单位为点；它既不是显示器分辨率，也不是包含标题栏的窗口外框尺寸。将它与 Size Class 并排展示，恰好可以对照“具体尺寸”和“空间分类”这两个层次。","\u002Fapi\u002Fmedia\u002Fposts\u002Fmacos27-ios-app-5fcd756b\u002F3.webp",{"local":25},{"headline":28,"body":29,"imageUrl":30,"images":31},"测试入口同样要选对。在 Xcode 中，应选择 My Mac (Designed for iPad)，运行","测试入口同样要选对。在 Xcode 中，应选择 My Mac (Designed for iPad)，运行 iOS App 的 Mac 版本。多平台项目里的普通 My Mac 则可能启动原生 macOS App。两者虽然都出现在 Mac 桌面上，观察结果却不能混为一谈。 在本次 macOS 27 实测中，拖动 iOS App 窗口，确实能够观察到 Size Class 随之变化。这个结果说明：至少在当前测试环境下，分类会随着窗口调整而更新，不能将启动时读到的值视作一成不变。 不过，窗口尺寸连续变化，Size Class 只有少量离散状态。拖动了一段距离，数值变了，分类保持原样，完全可能。此次观察也不足以归纳出适用于所有设备、系统版本和运行方式的固定阈值。把某次测得的宽度刻进代码，反倒容易刻舟求剑。 对 SwiftUI 开发者而言，接下来便顺理成章：让布局持续读取环境，在分类变化时重新组织内容。例如，在水平空间宽裕时并排展示两块内容，在紧凑时改为上下排列： 代码不必监听鼠标拖动，也不必把 Size Class 复制到一份额外的状态中。环境值更新后，SwiftUI 会重新求值，布局自然跟着调整。这里将 nil 一并落入纵向布局，是示例明确选择的回退策略。","\u002Fapi\u002Fmedia\u002Fposts\u002Fmacos27-ios-app-5fcd756b\u002F4.webp",{"local":30},{"headline":33,"body":34,"imageUrl":35,"images":36},"当然，Size Class 也不能包办所有适配。两块内容是否真的放得下，还受文字长度、字体大小和容器空间影响。决定界面的整体组织方式，可以参考 Size…","当然，Size Class 也不能包办所有适配。两块内容是否真的放得下，还受文字长度、字体大小和容器空间影响。决定界面的整体组织方式，可以参考 Size Class；判断一组按钮能否并排容纳，则更适合交给 ViewThatFits 或具体的布局计算。各司其职，才能游刃有余。 macOS 27 上的这次实验，把一个老道理摆到了眼前：用户手中的窗口，随时都可能改变界面的空间条件。 我们写下的是布局规则，用户决定的是窗口大小。让界面懂得因地制宜，拖动窗口时的从容，便会水到渠成。","\u002Fapi\u002Fmedia\u002Fposts\u002Fmacos27-ios-app-5fcd756b\u002F5.webp",{"local":35},[],[],{"name":40,"url":41},"Juejin","https:\u002F\u002Fjuejin.cn\u002Fpost\u002F7689263358284955699","zh",{"handle":44,"displayName":45},"spots","Spots",null,{"views":48,"likes":49,"saves":49,"shares":49,"completions":49,"opens":49,"skips":49,"depthSum":49},5,0,"2026-09-28T03:41:05.561Z","local"]