Sheet alternatives and similar libraries
Based on the "Alert & Action Sheet" category.
Alternatively, view Sheet alternatives based on common mentions on social networks and blogs.
-
Alerts & Pickers
Advanced usage of UIAlertController and pickers based on it: Telegram, Contacts, Location, PhotoLibrary, Country, Phone Code, Currency, Date... -
SPAlert
Native alert from Apple Music & Feedback. Contains Done, Heart & Message and other presets. [Moved to: https://github.com/ivanvorobei/SPAlert] -
StatusAlert
Display Apple system-like self-hiding status alerts. It is well suited for notifying user without interrupting user flow in iOS-like way. -
InAppNotify
Swift library to manage in app notification in swift language, like WhatsApp, Telegram, Frind, ecc. -
FloatingActionSheetController
FloatingActionSheetController is a cool design ActionSheetController library written in Swift2. -
PCLBlurEffectAlert
Swift AlertController with UIVisualeffectview -
ALRT
An easier constructor for UIAlertController. Present an alert from anywhere.
Appwrite - The Open Source Firebase alternative introduces iOS support
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Sheet or a related project?
README
Portrait | Landscape | Preview |
---|---|---|
![]() |
The above UI is built in a storyboard. It was lifted from Silver and required zero code changes to work as an action sheet.
Usage
final class ViewController: UIViewController {
private let sheetManager = Sheet(animation: .slideLeft)
private var observer: NSObjectProtocol?
override func viewDidLoad() {
super.viewDidLoad()
observer = NotificationCenter.default.addObserver(
forName: .dismiss,
object: nil,
queue: nil) { [weak self] _ in
self?.dismiss(animated: true)
}
sheetManager.chromeTapped = { [unowned self] in
self.dismiss(animated: true)
}
let action = #selector(tapGestureRecognized(_:))
let tapGesture = UITapGestureRecognizer(target: self, action: action)
view.addGestureRecognizer(tapGesture)
}
@objc func tapGestureRecognized(_ sender: UITapGestureRecognizer) {
let storyboard = UIStoryboard(name: "WelcomeSheet", bundle: nil)
let viewController = storyboard.instantiateInitialViewController()!
sheetManager.show(viewController, above: self)
}
}
The notification name dismiss
is created the typical way. You may create any name you like.
extension Notification.Name {
static let dismiss = Notification.Name(rawValue: "Dismiss")
}
Observed: by the controller that presents the action sheet. Posted: by the last controller in the action sheet sequence (or
didEnterBackground
for example).
Here are a sequence of two actions sheets WelcomeSheetViewController
being the 1st and CompleteSheetViewController
being the last.
class BaseViewController: UIViewController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.clipsToBounds = true
view.layer.cornerRadius = view.bounds.width * 0.1
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var prefersHomeIndicatorAutoHidden: Bool {
return true
}
}
final class WelcomeSheetViewController: BaseViewController {
@IBAction func startButtonPressed(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "CompleteSheet", bundle: nil)
let viewController = storyboard.instantiateInitialViewController()!
show(viewController, sender: self)
}
}
final class CompleteSheetViewController: BaseViewController {
@IBAction func finishButtonPressed(_ sender: UIButton) {
NotificationCenter.default.post(name: .dismiss, object: nil)
}
}
You may create a network of storyboard segue's, each segue pushing via
show
in storyboard or by calling UIKit'sshow
show(:sender:)
in code.
// iconImageView is an IBOutlet property to a UIImageView embedded in a stack view.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
iconImageView.isHidden = (traitCollection.verticalSizeClass == .compact)
}
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)
iconImageView.isHidden = (newCollection.verticalSizeClass == .compact)
coordinator.animate(alongsideTransition: { [unowned self] _ in
self.view.layoutIfNeeded()
}, completion: nil)
}
As per UIKit rules, each
UIViewController
subclass is responsible for it's views. So make sure your layout works in all environments. The above preview shows a paper plan icon which is hidden in compact height environments.
If you would like to use custom transition animations, instantiate Sheet
with .custom
and sublcass StoryboardSegue
.
final class FlipFromLeftSegue: StoryboardSegue {
override func executeTransition(_ completion: @escaping () -> Void) {
UIView.transition(
from: source.view!,
to: destination.view!,
duration: 0.3,
options: [.transitionFlipFromLeft]) { (_) in
completion()
}
}
}
final class DropSegue: StoryboardSegue {
override func executeTransition(_ completion: @escaping () -> Void) {
destination.view.layoutIfNeeded()
destination.view.transform = CGAffineTransform(translationX: 0, y: destination.view.bounds.height)
let height = source.view.bounds.height
UIView.animate(withDuration: 0.3, animations: {
self.source.view.transform = CGAffineTransform(translationX: 0, y: height)
self.destination.view.transform = CGAffineTransform.identity
}) { _ in
completion()
}
}
}
Demo
Tap the following image to launch Appetize.