Open djk3000 opened 2 years ago
起因是我希望这个框能够想sheet一样复用,sheet只能弹到顶部,ios16才有半屏的弹出框,所以就只能自己写一个自定义控件。 在这里就需要用到@ ViewBuilder来实现这个功能,他允许闭包中提供多个子视图,可以反复套用,将填充内容填进去。 就像原生控件Button一样 Button { //action } label: { //Conten } 这个label里面就可以自己填想要的Content,可以存放任何Content。
先上代码:
import SwiftUI struct BottomSheet<Content: View>: View { var sheetHeight: CGFloat = 420 @State var safeBottom: CGFloat = 0.0 @State var startingOffset: CGFloat = UIScreen.main.bounds.size.height @State var currentOffset: CGFloat = 0.0 @Binding var isShow: Bool @ViewBuilder var content: Content var body: some View { ZStack { if isShow{ Color("Button_PointOut") .zIndex(1) .onTapGesture { withAnimation { startingOffset = UIScreen.main.bounds.size.height isShow = false } } } ZStack(alignment: .top) { Color.clear ZStack{ content } .frame(maxWidth: .infinity, maxHeight: safeBottom + sheetHeight) .background(Color.white) .onAppear{ safeBottom = UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0.0 } } .frame(maxWidth: .infinity, maxHeight: .infinity) .cornerRadius(12) .zIndex(2) .offset(y: startingOffset) .offset(y: currentOffset) .gesture( DragGesture() .onChanged({ value in if currentOffset < 0{ return } withAnimation(.spring()){ currentOffset = value.translation.height } }) .onEnded({ value in withAnimation(.spring()){ if currentOffset > 100{ startingOffset = UIScreen.main.bounds.size.height isShow = false } currentOffset = 0 } }) ) } .onChange(of: isShow) { newValue in withAnimation { startingOffset = isShow ? startingOffset - safeBottom - sheetHeight : UIScreen.main.bounds.size.height } } } }
这里可以通过控制sheet的高度,然后点击按钮显示sheet,同时传递任意的Content进来 这里还是参考我之前写的那个手势拖拽的文章。
然后使用的地方:
BottomSheet(sheetHeight: 370, isShow: $showSheet){ //Content }
起因是我希望这个框能够想sheet一样复用,sheet只能弹到顶部,ios16才有半屏的弹出框,所以就只能自己写一个自定义控件。 在这里就需要用到@ ViewBuilder来实现这个功能,他允许闭包中提供多个子视图,可以反复套用,将填充内容填进去。 就像原生控件Button一样 Button { //action } label: { //Conten } 这个label里面就可以自己填想要的Content,可以存放任何Content。
先上代码:
这里可以通过控制sheet的高度,然后点击按钮显示sheet,同时传递任意的Content进来 这里还是参考我之前写的那个手势拖拽的文章。
然后使用的地方:
参考文档