测试已测试 | ✗ |
Lang语言 | Obj-CObjective C |
许可证 | MIT |
Released最后发布 | 2017年9月 |
由 Michal Zaborowski 维护。
MZFormSheetPresentationController
为原生 iOS UIModalPresentationFormSheet 提供了替代方案,增加了对 iPhone 的支持并提供了设置控制器尺寸和形式弹窗的更多机会。
MZFormSheetPresentationController
还定义了多种预定义的动画,您可以根据需要自定义模态表单是滑入、淡入、弹入还是创建自定义动画。还有许多属性可用于自定义表单的精确外观和位置。它还支持滑动手势取消。
该项目是 MZFormSheetController
的延续,允许您在部署目标设置为 >iOS5 时使用形式弹窗,但使用了某些巧妙的 UIWindow 拦截方法。
以下是几幅展示 MZFormSheetPresentationController
的图像
MZFormSheetPresentationController
以使用 UIPresentationController
shouldCenterHorizontally
属性由于作为主要版本变更,2.0 版本中引入的 API 与 1.x 集成不向后兼容。升级很简单。
使用 MZFormSheetPresentationViewController
而不是 MZFormSheetPresentationController
MZFormSheetPresentationController
现在继承自 UIPresentationController
并管理弹出窗口的显示
MZFormSheetPresentationViewController
包含属性 presentationController
,允许您自定义显示的内容视图
MZFormSheetPresentationController registerTransitionClass
现在是 MZTransition registerTransitionClass
函数 func entryFormSheetControllerTransition(formSheetController: MZFormSheetPresentationController, completionHandler: MZTransitionCompletionHandler)
已更改为 func entryFormSheetControllerTransition(formSheetController: UIViewController, completionHandler: MZTransitionCompletionHandler)
,其中 formSheetController 框架等于 contentViewSize 并具有视图原点。
MZFormSheetPresentationController 需要 iOS 8.x 或更高版本。
###Carthage
在您的 Cartfile
中添加以下行。
github "m1entus/MZFormSheetPresentationController" "master"
然后运行 carthage update --no-use-binaries
或只需 carthage update
。
在构建框架之后,您需要将其添加到您的项目中,并使用框架头文件导入它。
#import "<MZFormSheetPresentationController/MZFormSheetPresentationControllerFramework.h>"
有关Carthage的安装和使用细节,请访问其项目页面。
###CocoaPods
将以下行添加到您的 Podfile
中。
# Uncomment this line to define a global platform for your project
platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!
target 'ProjectName' do
pod 'MZFormSheetPresentationController'
end
然后运行 pod install --verbose
或只需 pod install
。有关CocoaPods的安装和使用详情,请访问其项目页面。
有两个示例项目,一个是Objective-C的,另一个是Swift的。
让我们从一个简单的例子开始
Objective-C
UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:@"formSheetController"];
MZFormSheetPresentationViewController *formSheetController = [[MZFormSheetPresentationViewController alloc] initWithContentViewController:navigationController];
formSheetController.presentationController.contentViewSize = CGSizeMake(250, 250); // or pass in UILayoutFittingCompressedSize to size automatically with auto-layout
[self presentViewController:formSheetController animated:YES completion:nil];
Swift
let navigationController = self.storyboard!.instantiateViewControllerWithIdentifier("formSheetController") as! UINavigationController
let formSheetController = MZFormSheetPresentationViewController(contentViewController: navigationController)
formSheetController.presentationController?.contentViewSize = CGSizeMake(250, 250) // or pass in UILayoutFittingCompressedSize to size automatically with auto-layout
self.presentViewController(formSheetController, animated: true, completion: nil)
这将在表单页面容器内显示视图控制器。
如果您想关闭表单页面控制器,请使用默认的关闭视图控制器动作。
Objective-C
[self dismissViewControllerAnimated:YES completion:nil];
Swift
self.dismissViewControllerAnimated(true, completion: nil)
很简单,对吧 ?!
如果您想将数据传递给显示视图控制器,您会像平常一样做。记住,IBOutlets在viewDidLoad之后初始化,如果您不想创建额外的属性,您始终可以使用完成块 willPresentContentViewControllerHandler
直接将数据传递到 outlets。它是在viewWillAppear之后和在 MZFormSheetPresentationViewController
动画之前调用的。
Objective-C
MZFormSheetPresentationViewController *formSheetController = [[MZFormSheetPresentationViewController alloc] initWithContentViewController:navigationController];
PresentedTableViewController *presentedViewController = [navigationController.viewControllers firstObject];
presentedViewController.textFieldBecomeFirstResponder = YES;
presentedViewController.passingString = @"PASSSED DATA!!";
formSheetController.willPresentContentViewControllerHandler = ^(UIViewController *vc) {
UINavigationController *navigationController = (id)vc;
PresentedTableViewController *presentedViewController = [navigationController.viewControllers firstObject];
[presentedViewController.view layoutIfNeeded];
presentedViewController.textField.text = @"PASS DATA DIRECTLY TO OUTLET!!";
};
[self presentViewController:formSheetController animated:YES completion:nil];
Swift
let formSheetController = MZFormSheetPresentationViewController(contentViewController: navigationController)
let presentedViewController = navigationController.viewControllers.first as! PresentedTableViewController
presentedViewController.textFieldBecomeFirstResponder = true
presentedViewController.passingString = "PASSED DATA"
formSheetController.willPresentContentViewControllerHandler = { vc in
let navigationController = vc as! UINavigationController
let presentedViewController = navigationController.viewControllers.first as! PresentedTableViewController
presentedViewController.view?.layoutIfNeeded()
presentedViewController.textField?.text = "PASS DATA DIRECTLY TO OUTLET!!"
}
self.presentViewController(formSheetController, animated: true, completion: nil)
typedef NS_OPTIONS(NSUInteger, MZFormSheetPanGestureDismissDirection) {
MZFormSheetPanGestureDismissDirectionNone = 0,
MZFormSheetPanGestureDismissDirectionUp = 1 << 0,
MZFormSheetPanGestureDismissDirectionDown = 1 << 1,
MZFormSheetPanGestureDismissDirectionLeft = 1 << 2,
MZFormSheetPanGestureDismissDirectionRight = 1 << 3,
MZFormSheetPanGestureDismissDirectionAll = MZFormSheetPanGestureDismissDirectionUp | MZFormSheetPanGestureDismissDirectionDown | MZFormSheetPanGestureDismissDirectionLeft | MZFormSheetPanGestureDismissDirectionRight
};
UINavigationController *navigationController = [self formSheetControllerWithNavigationController];
MZFormSheetPresentationViewController *formSheetController = [[MZFormSheetPresentationViewController alloc] initWithContentViewController:navigationController];
formSheetController.interactivePanGestureDissmisalDirection = MZFormSheetPanGestureDismissDirectionAll;
[self presentViewController:formSheetController animated:YES completion:nil];
您可以显示模糊背景,您可以将 MZFormSheetPresentationController
默认外观设置为模糊,或者直接将其设置为 MZFormSheetPresentationController
。
Objective-C
// Blur will be applied to all MZFormSheetPresentationControllers by default
[[MZFormSheetPresentationController appearance] setShouldApplyBackgroundBlurEffect:YES];
or
// This will set to only one instance
formSheetController.shouldApplyBackgroundBlurEffect = YES;
Swift
// Blur will be applied to all MZFormSheetPresentationControllers by default
MZFormSheetPresentationController.appearance().shouldApplyBackgroundBlurEffect = true
or
// This will set to only one instance
formSheetController.shouldApplyBackgroundBlurEffect = true
MZFormSheetPresentationViewController有自己的预定义转场。
Objective-C
typedef NS_ENUM(NSInteger, MZFormSheetPresentationTransitionStyle) {
MZFormSheetPresentationTransitionStyleSlideFromTop = 0,
MZFormSheetPresentationTransitionStyleSlideFromBottom,
MZFormSheetPresentationTransitionStyleSlideFromLeft,
MZFormSheetPresentationTransitionStyleSlideFromRight,
MZFormSheetPresentationTransitionStyleSlideAndBounceFromTop,
MZFormSheetPresentationTransitionStyleSlideAndBounceFromBottom,
MZFormSheetPresentationTransitionStyleSlideAndBounceFromLeft,
MZFormSheetPresentationTransitionStyleSlideAndBounceFromRight,
MZFormSheetPresentationTransitionStyleFade,
MZFormSheetPresentationTransitionStyleBounce,
MZFormSheetPresentationTransitionStyleDropDown,
MZFormSheetPresentationTransitionStyleCustom,
MZFormSheetPresentationTransitionStyleNone,
};
如果您想使用它们,您只需分配 contentViewControllerTransitionStyle
属性即可。
Objective-C
formSheetController.contentViewControllerTransitionStyle = MZFormSheetPresentationTransitionStyleFade;
您也可以通过实现 MZFormSheetPresentationViewControllerTransitionProtocol
协议并注册您自己的转场类作为自定义样式来创建自己的转场。
Objective-C
@interface CustomTransition : NSObject <MZFormSheetPresentationViewControllerTransitionProtocol>
@end
[MZTransition registerTransitionClass:[CustomTransition class] forTransitionStyle:MZFormSheetTransitionStyleCustom];
formSheetController.contentViewControllerTransitionStyle = MZFormSheetTransitionStyleCustom;
Swift
class CustomTransition: NSObject, MZFormSheetPresentationViewControllerTransitionProtocol {
}
MZTransition.registerTransitionClass(CustomTransition.self, forTransitionStyle: .Custom)
formSheetController.contentViewControllerTransitionStyle = .Custom
如果您正在创建自己的转场,您必须在动画结束时调用 completionBlock。
Objective-C
- (void)exitFormSheetControllerTransition:(nonnull UIViewController *)presentingViewController
completionHandler:(nonnull MZTransitionCompletionHandler)completionHandler {
CGRect formSheetRect = presentingViewController.view.frame;
formSheetRect.origin.x = [UIScreen mainScreen].bounds.size.width;
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
presentingViewController.view.frame = formSheetRect;
}
completion:^(BOOL finished) {
completionHandler();
}];
}
Swift
func exitFormSheetControllerTransition(presentingViewController: UIViewController, completionHandler: MZTransitionCompletionHandler) {
var formSheetRect = presentingViewController.view.frame
formSheetRect.origin.x = UIScreen.mainScreen().bounds.size.width
UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
presentingViewController.view.frame = formSheetRect
}, completion: {(value: Bool) -> Void in
completionHandler()
})
}
如果您想访问位于 MZFormSheetPresentationController 之下的控制器,您可以设置属性 transparentTouchEnabled
,背景视图控制器将获得所有触摸。
Objective-C
MZFormSheetPresentationViewController *formSheetController = [[MZFormSheetPresentationViewController alloc] initWithContentViewController:viewController];
formSheetController.presentationController.transparentTouchEnabled = YES;
Swift
let formSheetController = MZFormSheetPresentationViewController(contentViewController: viewController)
formSheetController.presentationController?.transparentTouchEnabled = true
/**
The handler to call when presented form sheet is before entry transition and its view will show on window.
*/
@property (nonatomic, copy, nullable) MZFormSheetPresentationViewControllerCompletionHandler willPresentContentViewControllerHandler;
/**
The handler to call when presented form sheet is after entry transition animation.
*/
@property (nonatomic, copy, nullable) MZFormSheetPresentationViewControllerCompletionHandler didPresentContentViewControllerHandler;
/**
The handler to call when presented form sheet will be dismiss, this is called before out transition animation.
*/
@property (nonatomic, copy, nullable) MZFormSheetPresentationViewControllerCompletionHandler willDismissContentViewControllerHandler;
/**
The handler to call when presented form sheet is after dismiss.
*/
@property (nonatomic, copy, nullable) MZFormSheetPresentationViewControllerCompletionHandler didDismissContentViewControllerHandler;
MZFormSheetPresentationController支持自动布局。
MZFormSheetPresentationController支持Storyboard。
MZFormSheetPresentationViewControllerSegue 是一个自定义Storyboard转场,它使用默认的MZFormSheetPresentationController设置。
如果您想通过Storyboard转场访问表单页面控制器并传递数据,代码将如下所示
Objective-C
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"segue"]) {
MZFormSheetPresentationControllerSegue *presentationSegue = (id)segue;
presentationSegue.formSheetPresentationController.presentationController.shouldApplyBackgroundBlurEffect = YES;
UINavigationController *navigationController = (id)presentationSegue.formSheetPresentationController.contentViewController;
PresentedTableViewController *presentedViewController = [navigationController.viewControllers firstObject];
presentedViewController.textFieldBecomeFirstResponder = YES;
presentedViewController.passingString = @"PASSSED DATA!!";
}
}
Swift
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
if identifier == "segue" {
let presentationSegue = segue as! MZFormSheetPresentationViewControllerSegue
presentationSegue.formSheetPresentationController.presentationController?.shouldApplyBackgroundBlurEffect = true
let navigationController = presentationSegue.formSheetPresentationController.contentViewController as! UINavigationController
let presentedViewController = navigationController.viewControllers.first as! PresentedTableViewController
presentedViewController.textFieldBecomeFirstResponder = true
presentedViewController.passingString = "PASSED DATA"
}
}
}
MZFormSheetPresentationController使用ARC。
某些位置计算访问 [UIApplication sharedApplication],这在应用扩展中是不允许的。如果您想在扩展中使用 MZFormSheetPresentationController,请在相应的目标中添加预处理器宏 MZ_APP_EXTENSIONS=1。
如果您使用Cocoapods,您可以使用post install钩子来完成此操作。
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "MZFormSheetPresentationController"
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'MZ_APP_EXTENSIONS=1'
end
end
end
end