在 SwiftUI 中,popover 是一种用来显示内容的小窗口,与 sheet 类似,但更适合用来展示临时信息或工具。popover 会根据设备和显示情况调整其显示方式,例如在 iPad 上作为浮动窗口,而在 iPhone 上通常以全屏形式展示。
用法跟Sheet类似,首先定义一个需要绑定的变量:
@State private var isPopoverPresented = false
在View视图中给视图添加popover:
Button("") {
}
.popover(isPresented: $isPopoverPresented) {
... // 浮窗内容
}
当点击Button时,iPad会显示浮窗内容,并以小窗口的形式展示。

基本用法
以下是 popover 的基本使用方式:
import SwiftUI
struct PopoverExample: View {
@State private var isPopoverPresented = false
var body: some View {
Button("Show Popover") {
isPopoverPresented.toggle()
}
.popover(isPresented: $isPopoverPresented, arrowEdge: .top) {
VStack {
Text("This is a popover!")
.padding()
Button("Dismiss") {
isPopoverPresented = false
}
}
.frame(width: 200, height: 200)
}
}
}
参数解释
isPresented: 控制 popover 的显示状态的 Binding<Bool>。
arrowEdge: 指定弹出方向(可选),如 .top、.leading 等。这个参数在 iPad 上更常见。
内容视图: popover 中显示的内容,支持任何 SwiftUI 视图。

适配iOS
需要注意的是,popover中iOS显示的是整个Sheet页面。

因此,可以考虑将popover和Sheet的自定义尺寸分别适配iOS和iPad。可通过horizontalSizeClass区别iOS和iPad:
import SwiftUI
struct ConditionalPopoverExample: View {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@State private var isPopoverPresented = false
var body: some View {
if horizontalSizeClass == .compact {
Button("Show Popover/Sheet") {
isPopoverPresented.toggle()
}
.sheet(isPresented: $isPopoverPresented) {
VStack {
Text("This is a sheet!")
.padding()
Button("Dismiss") {
isPopoverPresented = false
}
}
.presentationDetents([.height(100)])
}
} else {
Button("Show Popover/Sheet") {
isPopoverPresented.toggle()
}
.popover(isPresented: $isPopoverPresented, arrowEdge: .top) {
VStack {
Text("This is a popover!")
.padding()
Button("Dismiss") {
isPopoverPresented = false
}
}
.frame(width: 300, height: 300)
}
}
}
}
在iOS中显示自定义的小尺寸Sheet。

在iPad中使用popover显示浮窗。

样式调整
popover 的大小和布局是通过内部视图的 frame 控制的。例如:
.popover(isPresented: $isPopoverPresented, arrowEdge: .bottom) {
Text("Custom Size Popover")
.frame(width: 250, height: 150)
}
注意事项
1、环境适配:popover 在 iPhone 上通常显示为全屏,因此需要为小屏幕用户优化内容布局。
2、交互问题:确保 popover 和 sheet 之间的切换不会影响用户体验。
3、默认行为:在 iPad 上,popover 默认是浮动窗口;在 iPhone 上, popover 可能会自动转为全屏 sheet 显示。