☰
swiftui-expert-skill - latest-apis
2026/10/11 1:38:23 网站建设 项目流程

最新 SwiftUI API 参考

基于使用 Sosumi MCP 对 Apple 文档的比较,我们找到了推荐使用的最新 API。

本文件列出了什么是现代替代品。关于发现软废弃 API 时如何处理——何时迁移、何时保持不动、以及无关编辑的作用域规则——请参阅references/soft-deprecation.md。要在新的 SDK 发布后刷新此列表,请运行.agents/skills/update-swiftui-apis/SKILL.md中的维护技能。

目录

  • 始终使用(iOS 15+)
  • 当目标是 iOS 16+
  • 当目标是 iOS 17+
  • 当目标是 iOS 18+
  • 当目标是 iOS 26+

始终使用(iOS 15+)

这些 API 已被废弃足够久,没有理由再使用旧变体。

紧凑替代品

这些替代品的 API 形状变化最小。大多数是近乎直接的替换;少数需要额外的参数或结构调整:

  • navigationTitle(_:)代替navigationBarTitle(_:)
  • toolbar { ToolbarItem(...) }代替navigationBarItems(...)(结构性变化)
  • toolbarVisibility(.hidden, for: .navigationBar)代替navigationBarHidden(_:)
  • statusBarHidden(_:)代替statusBar(hidden:)
  • ignoresSafeArea(_:edges:)代替edgesIgnoringSafeArea(_:)
  • preferredColorScheme(_:)代替colorScheme(_:)
  • foregroundStyle(_:)代替foregroundColor(_:)(例如.foregroundStyle(.primary))
  • clipShape(.rect(cornerRadius:))代替cornerRadius()
  • textInputAutocapitalization(_:)代替autocapitalization(_:)(注意:.never取代.none)
  • animation(_:value:)代替animation(_:)(增加必需的value:参数;向后部署到 iOS 13+)

列表与表单

使用尾随闭包Section初始化器,而不是位置参数的 header/footer View 初始化器。

单一标题形式仍然是当前用法,不应视为已废弃:

// 当前 - 单一标题 LocalizedStringKey 初始化器Section("Settings"){Toggle("Notifications",isOn:.constant(true))}// 替代 - content/header/footer 尾随闭包初始化器Section{Toggle("Notifications",isOn:.constant(true))}header:{Text("Settings")}footer:{Text("Changes apply immediately.")}// 已废弃/重命名 - 位置参数 header/footer View 参数Section(header:Text("Settings"),footer:Text("Changes apply immediately.")){Toggle("Notifications",isOn:.constant(true))}Section(header:Text("Settings")){Toggle("Notifications",isOn:.constant(true))}Section(footer:Text("Changes apply immediately.")){Toggle("Notifications",isOn:.constant(true))}

呈现

  • 始终使用.confirmationDialog(_:isPresented:actions:message:)代替actionSheet(...)。
  • 始终使用.alert(_:isPresented:actions:message:)代替alert(isPresented:content:)。

两者都接受标题String、isPresented: Binding<Bool>、带Button项(支持role: .destructive/.cancel)的actions构建器,以及可选的message构建器:

.alert("Delete Item?",isPresented:$showAlert){Button("Delete",role:.destructive){deleteItem()}Button("Cancel",role:.cancel){}}message:{Text("This action cannot be undone.")}

文本输入

始终使用onSubmit(of:_:)和focused(_:equals:)代替TextField的onEditingChanged/onCommit回调。

@FocusStateprivatevarisFocused:BoolTextField("Search",text:$query).focused($isFocused).onSubmit{performSearch()}

无障碍

始终使用专门的无障碍修饰符,而不是通用的accessibility(...)变体。使用.accessibilityLabel()、.accessibilityValue()、.accessibilityHint()、.accessibilityAddTraits()、.accessibilityHidden()代替.accessibility(label:)、.accessibility(value:)等。

自定义环境/容器值

始终使用@Entry宏,而不是手动实现EnvironmentKey。@Entry宏在 Xcode 16 中引入,并向后部署到所有 OS 版本。

// 现代 — 一行取代约 10 行 EnvironmentKey 样板代码extensionEnvironmentValues{@EntryvarmyCustomValue:String="Default value"}

样式

始终使用Button而不是onTapGesture(),除非你需要点击位置或次数。

Button("Tap me"){performAction()}// 仅当你需要位置或次数时才使用 onTapGestureImage("photo").onTapGesture(count:2){handleDoubleTap()}

当目标是 iOS 16+

导航

使用NavigationStack(或NavigationSplitView)代替NavigationView。基于值的NavigationLink(value:)搭配.navigationDestination(for:)取代基于目的地的链接。

NavigationStack{List(items){iteminNavigationLink(value:item){Text(item.name)}}.navigationDestination(for:Item.self){DetailView(item:$0)}}

简单重命名

  • tint(_:)代替accentColor(_:)
  • autocorrectionDisabled(_:)代替disableAutocorrection(_:)

剪贴板

对于用户发起的粘贴 UI,优先使用PasteButton以避免粘贴提示。它会自动处理权限。仅当你需要编程式或非Transferable的剪贴板访问时才使用UIPasteboard(这会触发粘贴权限提示)。

PasteButton(payloadType:String.self){stringsinpastedText=strings.first??""}

当目标是 iOS 17+

状态管理

  • 新代码优先使用@Observable而不是ObservableObject。使用@State代替@StateObject;使用@Bindable代替@ObservedObject。完整的@Observable迁移模式请参阅state-management.md。

事件

使用onChange(of:initial:_:)或onChange(of:) { }代替onChange(of:perform:)。

已废弃的变体只传递新值。现代变体提供旧值和新值两者,或无参数闭包。

  • 无参数(最常见):.onChange(of: value) { doSomething() }
  • 旧值和新值:.onChange(of: value) { old, new in ... }
  • 带初始触发:.onChange(of: value, initial: true) { ... }
  • 已废弃:.onChange(of: value) { newValue in ... }—— 单参数闭包

感官反馈

在 SwiftUI 视图中,优先使用sensoryFeedback(_:trigger:)及相关重载,而不是UIImpactFeedbackGenerator、UISelectionFeedbackGenerator和UINotificationFeedbackGenerator。

以声明方式将触觉反馈附加到拥有状态变化的视图上,而不是在按钮动作中以命令式方式触发 UIKit 生成器。

@StateprivatevarisFavorite=falseButton("Favorite",systemImage:isFavorite?"heart.fill":"heart"){isFavorite.toggle()}.sensoryFeedback(.selection,trigger:isFavorite)

当反馈只应在特定状态转换时触发,使用条件重载:

.sensoryFeedback(.selection,trigger:phase){old,newinold==.inactive||new==.expanded}

手势

  • MagnifyGesture代替MagnificationGesture(通过value.magnification访问缩放量)
  • RotateGesture代替RotationGesture(通过value.rotation访问角度)

布局

考虑使用containerRelativeFrame()或visualEffect()作为GeometryReader在尺寸和基于位置的效果方面的替代方案。GeometryReader没有被废弃,并且对于许多基于测量的布局仍然是必需的。

Image("hero").resizable().containerRelativeFrame(.horizontal){length,axisinlength*0.8}
  • visualEffect { content, geometry in ... }—— 无需GeometryReader包装的基于位置的效果(视差、偏移)。
  • onGeometryChange(for:of:action:)—— 响应特定视图的几何变化;对驱动状态/效果很有用。当布局本身依赖几何信息时,GeometryReader仍然更好。注意双闭包形式:
    .onGeometryChange(for:CGFloat.self){proxyinproxy.size.height}action:{newHeightinheight=newHeight}
  • .coordinateSpace(.named("scroll"))代替.coordinateSpace(name: "scroll")。

当目标是 iOS 18+

标签页

使用TabAPI 代替tabItem(_:)。

TabView{Tab("Home",systemImage:"house"){HomeView()}Tab("Search",systemImage:"magnifyingglass"){SearchView()}Tab("Profile",systemImage:"person"){ProfileView()}}

当使用Tab(role:)时,所有标签页都必须使用Tab语法。将Tab(role:)与.tabItem()混用会导致编译错误。

预览

在预览中为动态属性使用@Previewable。

// 现代(iOS 18+)#Preview{@Previewable@StatevarisOn=falseToggle("Setting",isOn:$isOn)}

当目标是 iOS 26+

关于 Liquid Glass API(glassEffect、GlassEffectContainer、玻璃按钮样式),请参阅 liquid-glass.md。

滚动边缘效果

使用scrollEdgeEffectStyle(_:for:)配置滚动边缘行为。

ScrollView{// content}.scrollEdgeEffectStyle(.soft,for:.top)

背景扩展

使用backgroundExtensionEffect()实现边缘延伸的模糊背景。

Liquid Glass 侧边栏后面的视图可能出现被裁剪的情况。这个修饰符会镜像并模糊安全区之外的内容,使插画保持可见。

Image("hero").backgroundExtensionEffect()

来源:“Build a SwiftUI app with the new design”(WWDC25,会话 323)

标签栏

使用tabBarMinimizeBehavior(_:)控制标签栏在滚动时的最小化。

TabView{// tabs}.tabBarMinimizeBehavior(.onScrollDown)

使用tabViewBottomAccessory在标签栏上方放置持久控件。从环境中读取tabViewBottomAccessoryPlacement,以便在辅助项折叠进标签栏区域时调整内容。

TabView{// tabs}.tabViewBottomAccessory{NowPlayingBar()}

使用Tab(role: .search)创建专用的搜索标签页。该标签页会与其他标签页分离,并在选中时变形成搜索字段。

TabView{Tab("Home",systemImage:"house"){HomeView()}Tab("Profile",systemImage:"person"){ProfileView()}Tab(role:.search){SearchResultsView()}}

来源:“What’s new in SwiftUI”(WWDC25,会话 256)和 “Build a SwiftUI app with the new design”(WWDC25,会话 323)

工具栏

使用ToolbarSpacer控制工具栏项的编组。固定间距在视觉上分隔相关组;弹性间距将项推开。

.toolbar{ToolbarItem(placement:.topBarTrailing){Button("Up",systemImage:"chevron.up"){}}ToolbarItem(placement:.topBarTrailing){Button("Down",systemImage:"chevron.down"){}}ToolbarSpacer(.fixed)ToolbarItem(placement:.topBarTrailing){Button("Settings",systemImage:"gear"){}}}

使用sharedBackgroundVisibility(.hidden)从单个工具栏项移除玻璃组背景。

ToolbarItem(placement:.topBarTrailing){Image(systemName:"person.circle.fill").sharedBackgroundVisibility(.hidden)}

在工具栏项内容上使用badge(_:)显示指示器。

ToolbarItem(placement:.topBarTrailing){Button("Notifications",systemImage:"bell"){}.badge(unreadCount)}

来源:“Build a SwiftUI app with the new design”(WWDC25,会话 323)

搜索

使用searchToolbarBehavior(.minimizable)选择使用最小化的搜索按钮。系统可能会根据可用空间自动将搜索最小化为工具栏按钮。使用此修饰符显式选择启用。

NavigationStack{ContentView().searchable(text:$query).searchToolbarBehavior(.minimizable)}

来源:“Build a SwiftUI app with the new design”(WWDC25,会话 323)

动画

使用@Animatable宏代替手动animatableData声明。该宏从所有可动画属性自动合成animatableData。使用@AnimatableIgnored排除特定属性。

@AnimatablestructWedge:Shape{varstartAngle:AnglevarendAngle:Angle@AnimatableIgnoredvardrawClockwise:Boolfuncpath(inrect:CGRect)->Path{/* ... */}}

来源:“What’s new in SwiftUI”(WWDC25,会话 256)

呈现

使用navigationZoomTransition让 sheet 从其来源视图变形出现。工具栏项和按钮可以作为过渡来源。

.toolbar{ToolbarItem{Button("Add",systemImage:"plus"){showSheet=true}.navigationTransitionSource(id:"addSheet",namespace:namespace)}}.sheet(isPresented:$showSheet){AddItemView().navigationTransitionDestination(id:"addSheet",namespace:namespace)}

来源:“Build a SwiftUI app with the new design”(WWDC25,会话 323)

控件

使用controlSize(.extraLarge)制作超大号的突出操作按钮。

Button("Get Started"){}.buttonStyle(.borderedProminent).controlSize(.extraLarge)

对需要与容器边角匹配的按钮使用concentric边角样式。

Button("Confirm"){}.clipShape(.rect(cornerRadius:12,style:.concentric))

Slider 现在支持刻度标记和中性值。

Slider(value:$speed,in:0.5...2.0,step:0.25){Text("Speed")}ticks:{SliderTick(value:0.6)SliderTick(value:0.9)}.sliderNeutralValue(1.0)

来源:“Build a SwiftUI app with the new design”(WWDC25,会话 323)

富文本

使用带AttributedString绑定的TextEditor进行富文本编辑。支持粗体、斜体、下划线、删除线、自定义字体、前景/背景颜色、段落样式和 Genmoji。

@Stateprivatevartext:AttributedString="Hello, world!"varbody:someView{TextEditor(text:$text)}

来源:“Cook up a rich text experience in SwiftUI with AttributedString”(WWDC25,会话 280)

网页内容

使用WebView显示网页内容。对于更丰富的交互,创建一个可观察的WebPage模型。

// 简单的 URL 显示WebView(url:URL(string:"https://example.com")!)// 带可观察模型@Stateprivatevarpage=WebPage()WebView(page).onAppear{page.load(URLRequest(url:myURL))}.navigationTitle(page.title??"")

来源:“Meet WebKit for SwiftUI”(WWDC25,会话 231)

拖放

使用dragContainer进行多项目拖放操作。结合DragConfiguration实现自定义拖放行为,结合onDragSessionUpdated观察事件。

PhotoGrid(photos:photos).dragContainer(for:Photo.self){selectioninreturnselection.map{$0.transferable}}.onDragSessionUpdated{sessioninifsession.phase==.endedWithDelete{deleteSelectedPhotos()}}

来源:“What’s new in SwiftUI”(WWDC25,会话 256)

场景桥接

UIKit 和 AppKit 生命周期应用现在可以请求 SwiftUI 场景。这使得命令式生命周期应用可以通过UIApplication.shared.activateSceneSession(for:errorHandler:)使用仅 SwiftUI 的场景类型,如MenuBarExtra和ImmersiveSpace。

来源:“What’s new in SwiftUI”(WWDC25,会话 256)


快速查找表

已废弃推荐起始版本
navigationBarTitle(_:)navigationTitle(_:)iOS 15+
navigationBarItems(...)toolbar { ToolbarItem(...) }iOS 15+
navigationBarHidden(_:)toolbarVisibility(.hidden, for: .navigationBar)iOS 15+
statusBar(hidden:)statusBarHidden(_:)iOS 15+
edgesIgnoringSafeArea(_:)ignoresSafeArea(_:edges:)iOS 15+
colorScheme(_:)preferredColorScheme(_:)iOS 15+
foregroundColor(_:)foregroundStyle(_:)iOS 15+
cornerRadius(_:)clipShape(.rect(cornerRadius:))iOS 15+
actionSheet(...)confirmationDialog(...)iOS 15+
alert(isPresented:content:)alert(_:isPresented:actions:message:)iOS 15+
autocapitalization(_:)textInputAutocapitalization(_:)iOS 15+
accessibility(label:)等accessibilityLabel()等iOS 15+
TextFieldonCommit/onEditingChangedonSubmit+focusediOS 15+
animation(_:)(无 value)animation(_:value:)向后部署(iOS 13+)
Section(header:content:)Section(content:header:)未来废弃
Section(footer:content:)Section(content:footer:)未来废弃
Section(header:footer:content:)Section(content:header:footer:)未来废弃
手动EnvironmentKey@Entry宏向后部署(Xcode 16+)
NavigationViewNavigationStack/NavigationSplitViewiOS 16+
accentColor(_:)tint(_:)iOS 16+
disableAutocorrection(_:)autocorrectionDisabled(_:)iOS 16+
UIPasteboard.generalPasteButtoniOS 16+
onChange(of:perform:)onChange(of:) { }或onChange(of:) { old, new in }iOS 17+
UIImpactFeedbackGenerator/UISelectionFeedbackGenerator/UINotificationFeedbackGeneratorsensoryFeedback(_:trigger:)iOS 17+
MagnificationGestureMagnifyGestureiOS 17+
RotationGestureRotateGestureiOS 17+
coordinateSpace(name:)coordinateSpace(.named(...))iOS 17+
ObservableObject@ObservableiOS 17+
tabItem(_:)TabAPIiOS 18+
手动animatableData@Animatable宏iOS 26+
sheet 上的presentationBackground(_:)默认 Liquid Glass sheet 材质iOS 26+
自定义工具栏背景 hackscrollEdgeEffectStyle(_:for:)iOS 26+

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询