The original article was posted on my blog www.fatbobman.com
What is SheetKit
SheetKit is an enhanced library for SwiftUI modal views. Provides several convenient presentation and cancellation methods for modal views, as well as several View Extensions for modal views.
The main reasons for developing SheetKit:
-
Easy to call Deep Link
SwiftUI provides the onOpenURL method to make it easy for applications to respond to Deep Link. But in practice, the situation is not as expected. NavigationView, Sheet, SwiftUI, SwiftUI, SwiftUI, SwiftUI. It’s hard to get the application into the desired view state immediately with one or two lines of code.
-
Centralized management of modal views
SwiftUI usually uses. Sheet to create modal views. This is intuitive for simple applications, but if the logic of an application is complex and requires many modal views, this method can make the code confusing and difficult to tidy up. Therefore, in this case, we usually manage all modal views centrally and call them in one place. See my previous article – in SwiftUI, different sheets pop up on demand.
-
New semi-high modal view
With WWDC 2021, Apple brings a long-awaited semi-high modal view. Perhaps launched in a hurry, this popular interaction doesn’t offer SwiftUI, only UIKit. SheetKit makes up for that for now. No matter sheet, fullScreenCover or bottomSheet (semi-high modal view) are fully supported and managed uniformly.
System requirements
- iOS 15
- Swift, 5.5
- XCode 13.0 +
Simply strip modal view support, SheetKit will support iOS 14.
The installation
SheetKit supports SPM installation.
Source address
The code for each function in SheetKit is concentrated in one or two files. If only part of the functionality is needed, it might be a good idea to add the corresponding files directly to the project.
SheetKit features in detail
present
SheetKit call
SheetKit is easy to use in your code. Two options are supported: directly using SheetKit instances or using environment values in views. For example, the following two pieces of code will display a standard Sheet:
Button("show sheet") {SheetKit().present{
Text("Hello world")}}Copy the code
or
@Environment(\.sheetKit) var sheetKit
Button("show sheet"){
sheetKit.present{
Text("Hello world")}}Copy the code
SheetKit supports displaying multiple layers of sheets, and the code below displays two layers of sheets
@Environment(\.sheetKit) var sheetKit
Button("show sheet"){
sheetKit.present{
Button("show full sheet"){
sheetKit.present(with:.fullScreenCover){
Text("Hello world")}}}}Copy the code
animation
Present and Dismiss animations in SheetKit can be closed (especially for Deep Link scenarios). Use the following statement to turn off the display animation
SheetKit().present(animated: false)
Copy the code
Sheet type
SheetKit currently supports three modal view types: Sheet, fullScreenCover and bottomSheet.
The following code shows a default bottomSheet view:
sheetKit.present(with: .bottomSheet){
Text("Hello world")}Copy the code
The bottomSheet configuration can be customized.
The following code will create a custom bottomSheet
let configuration = SheetKit.BottomSheetConfiguration(detents: [.medium(),.large()],
largestUndimmedDetentIdentifier: .medium,
prefersGrabberVisible: true,
prefersScrollingExpandsWhenScrolledToEdge: false,
prefersEdgeAttachedInCompactHeight: false,
widthFollowsPreferredContentSizeWhenEdgeAttached: true,
preferredCornerRadius: 100)
sheetKit.present(with: .customBottomSheet,configuration: configuration) {
Text("Hello world")}Copy the code
Modal view height change alert
There are two ways to get alerts when bottomSheet changes at different heights.
Method 1:
@State var detent:UISheetPresentationController.Detent.Identifier = .medium
Button("Show"){
sheetKit.present(with: .bottomSheet,detentIdentifier: $detent) {Text("Hello worl")
}
}
.onChange(of: detent){ value in
print(value)
}
Copy the code
Method 2:
@State var publisher = NotificationCenter.default.publisher(for: .bottomSheetDetentIdentifierDidChanged, object: nil)
.onReceive(publisher){ notification in
guard let obj = notification.object else {return}
print(obj)
}
Copy the code
If multiple layers of bottomSheet need to be displayed in Method 2, define different names of notification. Name for views at different layers
dismissAllSheets
SheetKit supports quick cancellation of all modal views being displayed (whether or not the modal view is displayed by SheetKit). Use the following code
SheetKit().dismissAllSheets()
Copy the code
Support animation control and onDisappear
SheetKit().dismissAllSheets(animated: false, completion: {
print("sheet has dismiss")})Copy the code
dismiss
If you just want to cancel the topmost modal view, you can use dismiss
SheetKit().dismiss()
Copy the code
Animation control is also supported
If you execute the SheetKit method outside of a view, make sure your code runs on the main thread. You can use dispatchqueue.main. async or mainactor.run.
interactiveDismissDisabled
SwiftUI interactiveDismissDisabled strengthen version 3.0, through code control whether to allow gestures to cancel, on the basis of increased when the user can gain the ability to notice when using gestures to cancel.
For more information, please refer to how to implement in SwiftUI interactiveDismissDisabled
The interactiveDismissDisabled SheetKit to compatible bottomSheet made certain changes, specific see the source code changes.
struct ContentView: View {
@State var sheet = false
var body: some View {
VStack {
Button("show sheet") {
sheet.toggle()
}
}
.sheet(isPresented: $sheet) {
SheetView()}}}struct SheetView: View {
@State var disable = false
@State var attempToDismiss = UUID(a)var body: some View {
VStack {
Button("disable: \(disable ? "true" : "false")") {
disable.toggle()
}
.interactiveDismissDisabled(disable, attempToDismiss: $attempToDismiss)
}
.onChange(of: attempToDismiss) { _ in
print("try to dismiss sheet")}}}Copy the code
clearBackground
Set the background of the modal view to transparent. In SwiftUI3.0, you can already generate a variety of frosted glass effects using the native API. But the frosted glass effect can only be seen if the modal view’s background is set to transparent.
In modal view:
.clearBackground()
Copy the code
Such as:
ZStack {
Rectangle().fill(LinearGradient(colors: [.red, .green, .pink, .blue, .yellow, .cyan, .gray], startPoint: .topLeading, endPoint: .bottomTrailing))
Button("Show bottomSheet") {
sheetKit.present(with: .bottomSheet, afterPresent: { print("presented") }, onDisappear: { print("disappear") }, detentIdentifier: $detent) {
ZStack {
Rectangle()
.fill(.ultraThinMaterial)
VStack {
Text("Hello world")
Button("dismiss all") {
SheetKit().dismissAllSheets(animated: true, completion: {
print("sheet has dismiss")
})
}
}
}
.clearBackground()
.ignoresSafeArea()
}
}
.foregroundColor(.white)
.buttonStyle(.bordered)
.controlSize(.large)
.tint(.green)
}
.ignoresSafeArea()
Copy the code
conclusion
Both SheetKit and NavigationViewKit are extensions for developing new versions of health Notes. The functions are based on my personal needs. Please let me know if there are any other features you need via Twitter, blog comments or Issues.
I hope this article has been helpful to you.
This article originally appeared on my blog [Elbow’s Swift Notepad]
Welcome to subscribe to my public number: Elbow Swift Notepad
Other recommendations:
Core Data with CloudKit 1-6
How to preview SwiftUI view with Core Data elements in Xcode
www.fatbobman.com/posts/uikit…
Enhance SwiftUI’s navigation view with NavigationViewKit
@ AppStorage research