ModalKit 是一个简单且灵活的框架,用于管理 iOS 中的模态视图呈现。它支持自定义动画、可配置的呈现尺寸和交互手势。ModalKit 简化了创建动态和用户友好的模态界面的过程。
⚠️ 重要提示
当前版本仍在开发中。在 1.0 版本之前,版本更新可能会有破坏性变更。
多个粘滞点
:在预定义的模态高度之间转换,例如小、中和大。滚动视图集成
:无缝处理滚动视图,实现滚动和拖动手势之间的平滑过渡。动态调整大小
:以编程方式或基于内容更改来调整模态视图的大小。使用 ModalKit 呈现一个视图控制器
import ModalKit
let viewControllerToPresent = MyViewController()
presentModal(viewControllerToPresent)
import ModalKit
let viewControllerToPresent = MyViewController()
viewControllerToPresent.modalPresentationStyle = .custom
viewControllerToPresent.transitioningDelegate = MKPresentationManager()
present(viewControllerToPresent, animated: true)
以编程方式关闭模态视图
self.dismiss(animated: true, completion: nil)
ModalKit 支持多种呈现尺寸,可以使用 MKPresentationSize
枚举来定义
.large
:全屏呈现。.medium
:半屏呈现。.small
:四分之一屏呈现。.contentHeight(CGFloat)
:固定高度。.intrinsicHeight
:根据内容大小自动调整。.additionalHeight(MKPresentationSize, CGFloat)
:允许指定相对于另一个呈现尺寸的额外偏移高度。您可以在 preferredPresentationSize 中提供多个选项。模态可以吸附到任何合适的尺寸。
示例
class MyViewController: MKPresentable {
var preferredPresentationSize: [MKPresentationSize] {
return [.small, .intrinsicHeight, .large]
}
您也可以通过编程方式将模态视图转换到不同的尺寸
self.transition(to: .medium)
此方法使模态视图以动画形式过渡到新的尺寸,同时遵守 MKPresentationSize
定义的约束。这对于需要根据用户交互或内容更改动态调整的模态视图特别有用。
视图控制器可以遵循 MKPresentable 协议来自定义它们的呈现方式。此协议使您可以精细控制
下面是一个基本遵循的示例,它还演示了您可以重写的可选方法,以完全控制模态视图的行为,包括过渡和滚动行为
extension MyViewController: MKPresentable {
// Defines the possible sizes for the presented view controller (e.g., medium & large).
var preferredPresentationSize: [MKPresentationSize] {
return [.medium, .large]
}
// If your view contains a scroll view (like a UITableView), provide it here.
// ModalKit will observe its offset to seamlessly hand off between scrolling and dragging the modal.
var scrollView: UIScrollView? {
return myTableView
}
// Called once before the modal is presented. Use this to configure drag indicators,
// corner radius, and other presentation options.
func configure(_ configuration: inout MKPresentableConfiguration) {
configuration.showDragIndicator = true
configuration.hasRoundedCorners = true
}
// Called when the dimming view is tapped.
// By default, this dismisses the modal. Override for custom behavior.
func onDimmingViewTap() {
dismiss(animated: true)
}
// Return false if you want to disallow certain drag gestures (e.g., under some conditions).
// By default, this returns true, letting the modal's pan gesture proceed.
func shouldContinue(with gestureRecognizer: UIPanGestureRecognizer) -> Bool {
return true
}
// Called right before the modal tries to switch to a new size (e.g., from .small to .medium).
// Return false to block that transition. By default, this returns true.
func shouldTransition(to size: MKPresentationSize) -> Bool {
return true
}
// Called immediately before the modal begins resizing to the new size.
// Use this to update your UI (e.g., hiding certain subviews).
func willTransition(to size: MKPresentationSize) {
// e.g., hide a toolbar
}
// Called after the modal has finished transitioning to the new size.
// Use this to finalize any layout changes or re-display elements.
func didTransition(to size: MKPresentationSize) {
// e.g., show the toolbar again
}
}
ModalKit 提供了在运行时处理布局更改的方法,确保模态视图在内容或约束更改时正确调整。这对于动态内容(例如更新的文本、添加的视图或大小要求更改)特别有用。
如果模态视图的布局受到内容更改或外部更新的影响,您可以手动触发重新计算,以确保模态视图调整到新的尺寸。通过调用 presentationLayoutIfNeeded()
方法,模态视图会更新其布局,并根据 preferredPresentationSize
或其他定义的尺寸配置以动画形式移动到正确的位置
self.updateUI()
self.presentationLayoutIfNeeded()
MKPresentableConfiguration 提供了多种选项
选项 | 描述 |
---|---|
showDragIndicator |
指示是否应在模态视图的顶部显示拖动指示器。默认值:false 。 |
dragIndicatorColor |
拖动指示器的颜色(如果已启用)。默认值:.label 。 |
dragIndicatorSize |
拖动指示器的大小(如果已显示)。默认值:CGSize(width: 40, height: 5) 。 |
dismissibleScale |
自动关闭视图控制器的缩放比例。默认值:0.6 。 |
isDismissable |
确定是否可以通过拖动关闭模态视图。默认值:true 。 |
dragResistance |
指定模态视图对拖动手势的阻力,范围从 0.0 (无阻力)到 1.0 (完全阻力)。默认值:0 。 |
hasRoundedCorners |
指示模态视图是否应具有圆角。默认值:false 。 |
ModalKit 提供对 UIScrollView
及其子类(例如 UITableView
和 UICollectionView
)的内置支持,允许滚动和模态手势之间进行无缝交互。ModalKit
确保在滚动内容与用于调整大小或关闭模态视图的拖动手势重叠时平滑过渡。
要启用滚动视图集成,请实现 MKPresentable
协议并在 scrollView
属性中返回您的滚动视图
class MyViewController: MKPresentable {
var scrollView: UIScrollView? {
return myTableView
}
}
滚动和拖动之间的切换:当滚动视图位于其内容的顶部或底部时,拖动手势会无缝过渡到调整大小或关闭模态视图。ModalKit 观察滚动视图的内容偏移量,以确定何时允许拖动或保持滚动行为。
如果需要自定义滚动视图和模态视图之间的交互,可以在 MKPresentable 协议中重写 shouldContinue(with:) 方法
class MyViewController: MKPresentable {
var scrollView: UIScrollView? {
return myTableView
}
func shouldContinue(with gestureRecognizer: UIPanGestureRecognizer) -> Bool {
// Custom logic to determine if dragging should continue
return true
}
}
ModalKit 也能很好地与
UITabBarController 配合使用,确保模态视图呈现在标签栏之上,而不会干扰其功能。
ModalKit` 自动处理安全区域插图,并调整模态视图的布局以避免与标签栏重叠。
class MyTabBarViewController: UITabBarController, MKPresentable {
/// The preferred presentation size for the currently selected view controller.
var preferredPresentationSize: [MKPresentationSize] {
if let vc = selectedViewController as? MKPresentable {
return vc.preferredPresentationSize
}
return [.large]
}
}
ModalKit
与 UINavigationController 完全兼容,允许在导航堆栈中呈现模态视图。它还支持推送的视图控制器和模态呈现的视图之间的平滑过渡。
class MyNavigationViewController: UINavigationController, UINavigationControllerDelegate, MKPresentable {
/// Returns the preferred presentation size of the top view controller if it conforms to `MKPresentable`,
/// otherwise defaults to `.large`.
var preferredPresentationSize: [MKPresentationSize] {
if let vc = topViewController as? MKPresentable {
return vc.preferredPresentationSize
}
return [.large]
}
override var preferredStatusBarStyle: UIStatusBarStyle { .lightContent }
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
guard !navigationController.isBeingPresented else { return }
/// Ensures the presentation layout is updated when transitioning between view controllers.
presentationLayoutIfNeeded()
}
}
ModalKitExample
项目提供了各种用法示例。这些示例展示了如何为不同的用例实现和自定义 ModalKit。请浏览 ModalKitExample
项目以获取更多详细信息。
要使用 Swift Package Manager 将 ModalKit
集成到您的项目中,请将以下内容添加到您的 Package.swift
文件中
dependencies: [
.package(url: "https://github.com/emrearmagan/ModalKit.git")
]
欢迎贡献!如果您想贡献,请在 GitHub 上打开一个 pull request 或 issue。
ModalKit
在 MIT 许可证下可用。有关更多信息,请参见 LICENSE 文件。