我正在尝试实现模态演示效果,其中所呈现的视图仅部分覆盖父视图,如下图所示。
我知道我可以通过使用UIPresentationController
实现自定义转换来实现这一目标。在我开始进行开发之前,我不想重新发明轮子,我想问一下。
是否支持API中的此类转换?
我研究了所有可用的Modal Presentation Styles,在我看来,我不支持我想要进行的转换,实现它的唯一方法就是编写代码。
答案 0 :(得分:5)
我遇到了同样的问题。我也沿着模态演示风格路线走下去,不停地撞墙(特别是让它在iPhone而不是iPad上工作)。
经过一番挖掘后,我能够让它运转起来。以下是我的表现方式:首先,我们需要一个我们将要呈现的视图控制器(模态一)将其视图的背景颜色设置为透明并设置导航控制器视图的框架一些抵消。
@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
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:animated:completion
这就是我做的
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
答案 1 :(得分:0)
非常确定它是这样做的
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)
}
答案 2 :(得分:-1)
我很确定这是你的答案 - 页面表 - 如在UIModalPresentationPageSheet中