我正在尝试实现模态呈现效果,其中所呈现的视图仅部分覆盖父视图,如下图所示.
我知道我可以通过使用UIPresentationController实现自定义转换来实现这一点.我不想重新发明,所以在我开始发展之前,我想问一下.
在API中是否有这种转型的支持?
我研究了所有可用的Modal Presentation Styles,在我看来,我不想支持我想要的转换,唯一的方法就是编写它.
解决方法
我遇到了同样的问题.我也去了模式演示风格的路线,并不断击中墙壁(具体让它在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
接下来,我们需要设置演示控制器来运行以下动画:
>缩小自己
淡出一点点
>使用presentViewController呈现模态视图控制器:动画:完成
这就是我所做的
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