大众号:RobotPBQ

在苹果升级到iOS16后,给sheet带来了十分好用的一个功用 presentationDetents高度能够自由操控,在iOS16之前高度是固定的,但是在iOS16以后你能够用sheet创造很多app中流行的作用。

presentationDetents 介绍

SwiftUI 中,sheet 修饰符的 presentationDetents 参数用于操控 sheet 被拖拽时的停靠位置。

presentationDetents 能够设置以下值:

  • .fraction(0.0) – 禁止停靠,可全范围拖拽
  • .fraction(0.5) – 中心停靠点
  • .fraction(1.0) – 最大停靠点
  • .medium – 预设中等停靠点
  • .large – 预设大停靠点

比如:

.sheet(isPresented: $showSheet) {
   // sheet内容 
}
.presentationDetents([.fraction(0.5)])

这将答应sheet被拖拽,并在屏幕笔直中心点停靠。

经过装备presentationDetents,能够操控sheet的拖拽和停靠交互,完成更丰富的用户体验。一般结合.interactive()运用。

他有两种初始化办法

办法一
public func presentationDetents(_ detents: Set<PresentationDetent>) -> some View
办法二
public func presentationDetents(_ detents: Set<PresentationDetent>, selection: Binding<PresentationDetent>) -> some View

第一个参数是一个Set集合, 内部类型是PresentationDetent. 内部供给了四种简便的办法来让你便利的操控高度

public struct PresentationDetent : Hashable {
    public static let medium: PresentationDetent // 高度大约是屏幕的一半
    public static let large: PresentationDetent // 和Sheet的高度相同
    public static func fraction(_ fraction: CGFloat) -> PresentationDetent // 屏幕的小数点份额,例如:0.5,就是屏幕的一半高度
    public static func height(_ height: CGFloat) -> PresentationDetent // 单位是PX,设置200,那么高度就是200

有了以上根本知道,咱们来具体看看示例

先给出一个本来运用 sheet 的办法

struct ResizableSheetSample: View {
  @State var showSheet: Bool = false
  var body: some View {
    Button {
      showSheet.toggle()
    } label: {
      Text("Click me")
    }
    .sheet(isPresented: $showSheet) {
      MyCustomeView()
    }
  }
}
struct MyCustomeView: View {
  var body: some View {
    ZStack {
      Color.mint.ignoresSafeArea()
    }
  }
}

作用就是点击按钮,会弹出一个青色布景色的页面

SwiftUI - 可变高度的Sheet

presentationDetents 运用

大视图

这个作用和之前默认的作用是一样的

MyCustomeView()
.presentationDetents([.large])
SwiftUI - 可变高度的Sheet

中等企图

弹出的页面只有页面的一半高度

MyCustomeView()
.presentationDetents([.medium])
SwiftUI - 可变高度的Sheet

指定高度

弹出页面的高度为指定高度,单位为:PX

MyCustomeView()
.presentationDetents([.height(100)])
SwiftUI - 可变高度的Sheet

指定份额

弹出页面占整个页面的份额,范围为:0 ~ 1

MyCustomeView()
.presentationDetents([.fraction(0.6)])
SwiftUI - 可变高度的Sheet

是否躲藏指示器

能够躲藏或显现指示器,就是图片中绿色布景顶部的小黑杠

.presentationDragIndicator(.visible)
SwiftUI - 可变高度的Sheet

interactiveDismissDisabled 参数运用

运用此参数,弹出的sheet页面将无法收回。

.interactiveDismissDisabled()
SwiftUI - 可变高度的Sheet

完成不同位置的悬停

presentationDetents 能够设置多个值,完成不同位置的悬停作用

.presentationDetents([.fraction(0.3), .large, .medium, .height(130)])
SwiftUI - 可变高度的Sheet

在子页面改动页面的高度

要完成在子页面来改动页面的高度,咱们就需要运用另一个办法来完成,它多了一个参数

public func presentationDetents(_ detents: Set<PresentationDetent>, selection: Binding<PresentationDetent>) -> some View
怎么运用

咱们需要在父视图传递一个参数到子视图

// 父视图
MyCustomeView(detentState: $detentState)
    .presentationDetents(
    [.fraction(0.3), .large, .medium, .height(600)],
    selection: $detentState
    )
// 子视图
struct MyCustomeView: View {
    @Binding var detentState: PresentationDetent
  var body: some View {
    ZStack {
      Color.mint.ignoresSafeArea()
      VStack(spacing: 30) {
        Button("large") {
          detentState = .large
        }
        Button("medium") {
          detentState = .medium
        }
        Button("height") {
          detentState = .height(600)
        }
        Button("fraction") {
          detentState = .fraction(0.3)
        }
      }
      .foregroundColor(.black)
    }
  }
}

咱们在子视图中去改动这个值,就能够达到改动页面高度的作用

SwiftUI - 可变高度的Sheet

我们有什么观点呢?欢迎留言讨论。