假设我们有以下需求:
自定义一个 sheet ,当 iOS 版本为 16.0 以上时,可以指定弹出 sheet 的高度,而当 iOS 版本为 16.0 以下时,弹出的 sheet 为默认高度。
sheet 的官方声明如下
func sheet
因此我们必须向它传递 isPresented
和 content
两个参数,再加上我们指定的高度,总共需要传递三个参数给我们的 modifier,代码如下:
import SwiftUI
struct customSheetModifier<SheetContent: View>: ViewModifier {
@Binding var isPresented: Bool
var fraction: CGFloat = 0.5
var sheetContent: () -> SheetContent
func body(content: Content) -> some View {
Group {
if #available(iOS 16.0, *) {
content
.sheet(isPresented: $isPresented) {
sheetContent()
.presentationDetents([.fraction(fraction)])
}
} else {
content
.sheet(isPresented: $isPresented) {
sheetContent()
}
}
}
}
}
这里我们使用了 Swift 的泛型来实现。
为了使用更便利,我们可以创建以下的 extension 来使用我们的 modifier:
extension View {
func customSheet<SheetContent>(isPresented: Binding<Bool>, fraction: CGFloat = 0.5, sheetContent: @escaping () -> SheetContent) -> some View where SheetContent: View {
modifier(customSheetModifier(isPresented: isPresented,fraction: fraction, sheetContent: sheetContent))
}
}
这样,我们只需要在 View 中使用 .customSheet
即可调用自定义的 sheet 了。
使用方法如下:
在需要使用自定义 sheet 的 View 中,使用 .customSheet
modifier 即可。例如:
@State var sheetPresented = false
var body: some View {
Button("Show Sheet") {
sheetPresented.toggle()
}
.customSheet(isPresented: $sheetPresented, fraction: 0.7) {
SheetView()
}
}
其中,SheetView()
为自定义的 sheet 内容,fraction
参数为我们指定的高度占屏幕的比例。