SwiftUI 自定义一个以 View 作为参数的 ViewModifier

SwiftUI 自定义一个以 View 作为参数的 ViewModifier

假设我们有以下需求:

自定义一个 sheet ,当 iOS 版本为 16.0 以上时,可以指定弹出 sheet 的高度,而当 iOS 版本为 16.0 以下时,弹出的 sheet 为默认高度。

sheet 的官方声明如下

func sheet<Content>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping () -> Content) -> some View where Content : View

因此我们必须向它传递 isPresentedcontent 两个参数,再加上我们指定的高度,总共需要传递三个参数给我们的 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 参数为我们指定的高度占屏幕的比例。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值