像在邮件应用程序中的模式转换样式
我试图实现一个模式的演示效果,其中呈现的视图只覆盖了父视图的一部分,如下图所示。
我知道我可以通过使用UIPresentationController
实现自定义转换来实现这UIPresentationController
。 我不想重新发明轮子,所以在开发之前,我想问一下。
是否有构build支持API中的这种转换?
我研究了所有可用的Modal Presentation Styles ,看起来我并不支持我想要做的转换,而实现它的唯一方法就是编写它。
我遇到了同样的问题。 我沿着模式performance风格的路线,并不断打墙(特别是使它在iPhone而不是iPad上)。
经过一番挖掘,我能够得到它的工作。 以下是我如何做到的:
首先,我们需要一个我们将呈现的视图控制器(模态)来将其视图的背景颜色设置为透明,并将导航控制器视图的框架设置为某个偏移量。
ModalViewController.h
@import UIKit; @class ModalViewController; @protocol ModalViewControllerDelegate <NSObject> - (void)modalViewControllerDidCancel:(ModalViewController *)modalViewController; @end @interface ModalViewController : UIViewController @property (weak, nonatomic) id<ModalViewControllerDelegate> delegate; - (instancetype)initWithRootViewController:(UIViewController *)rootViewController; @end
ModalViewController.m
static const CGFloat kTopOffset = 50.0f; @implementation ModalViewController { UINavigationController *_navController; } - (instancetype)initWithRootViewController:(UIViewController *)rootViewController { self = [super initWithNibName:nil bundle:nil]; if (self) { rootViewController.navigationItem.leftBarButtonItem = [self cancelButton]; _navController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; self.view.backgroundColor = [UIColor clearColor]; [self.view addSubview:_navController.view]; // this is important (prevents black overlay) self.modalPresentationStyle = UIModalPresentationOverFullScreen; } return self; } - (void)viewDidLoad { [super viewDidLoad]; CGRect bounds = self.view.bounds; _navController.view.frame = CGRectMake(0, kTopOffset, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - kTopOffset); } - (UIBarButtonItem *)cancelButton { return [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonClicked:)]; } - (void)cancelButtonClicked:(id)sender { [_delegate modalViewControllerDidCancel:self]; } @end
接下来,我们需要设置呈现控制器来运行以下animation:
- 缩小自己
- 淡出一点点
- 使用
presentViewController:animated:completion
模态视图控制器presentViewController:animated:completion
这就是我所做的
PresentingViewController.m
static const CGFloat kTransitionScale = 0.9f; static const CGFloat kTransitionAlpha = 0.6f; static const NSTimeInterval kTransitionDuration = 0.5; @interface PresentingViewController <ModalViewControllerDelegate> @end @implementation PresentingViewController ... ... - (void)showModalViewController { self.navigationController.view.layer.shouldRasterize = YES; self.navigationController.view.layer.rasterizationScale = [UIScreen mainScreen].scale; UIViewController *controller = // init some view controller ModalViewController *container = [[ModalViewController alloc] initWithRootViewController:controller]; container.delegate = self; __weak UIViewController *weakSelf = self; [UIView animateWithDuration:kTransitionDuration animations:^{ weakSelf.navigationController.view.transform = CGAffineTransformMakeScale(kTransitionScale, kTransitionScale); weakSelf.navigationController.view.alpha = kTransitionAlpha; [weakSelf presentViewController:container animated:YES completion:nil]; } completion:^(BOOL finished) { weakSelf.navigationController.view.layer.shouldRasterize = NO; }]; } #pragma mark - ModalViewControllerDelegate - (void)modalViewControllerDidCancel:(ModalViewController *)modalViewController { __weak UIViewController *weakSelf = self; [UIView animateWithDuration:kTransitionDuration animations:^{ weakSelf.navigationController.view.alpha = 1; weakSelf.navigationController.view.transform = CGAffineTransformIdentity; [weakSelf dismissViewControllerAnimated:YES completion:nil]; }]; } @end
我很确定这是你的答案 – 页面表 – 如在UIModalPresentationPageSheet
很确定它是这样做的
let newVC = <view controller you want to display> let nav: UINavigationController = UINavigationController(rootViewController: newVC) if let currVc = UIApplication.sharedApplication().keyWindow?.rootViewController { nav.transitioningDelegate = currVc nav.modalPresentationStyle = UIModalPresentationStyle.Custom; currVc.presentViewController(nav, animated: true, completion: nil) }