我正在研究实现如下图所示的自定义弹出对话框,并且遇到了各种方法来实现此目标。自定义弹出对话框
1-调用被定位这增加覆盖到当前视图层次结构和动画的方式向屏幕
2-使用UIPresentationController的中心这需要大量代码
屏幕的外部的View
3使用pod
我想知道iOS中这种'弹出窗口的当前状态是什么,哪些是最简单和最直接的实现。
我正在寻找一个答案,彻底比较现有的选项,并清楚地展示每个的利弊。
我正在研究实现如下图所示的自定义弹出对话框,并且遇到了各种方法来实现此目标。自定义弹出对话框
1-调用被定位这增加覆盖到当前视图层次结构和动画的方式向屏幕
2-使用UIPresentationController的中心这需要大量代码
屏幕的外部的View
3使用pod
我想知道iOS中这种'弹出窗口的当前状态是什么,哪些是最简单和最直接的实现。
我正在寻找一个答案,彻底比较现有的选项,并清楚地展示每个的利弊。
如果要支持的iOS 8及以上的(你应该是,如果可能的话!)我会建议使用一个UIViewController有UIPresentationController处理的背景幕视图。
我的理由:
•这些都是很新的,100%原生API。
•Apple对自己的一些API(请参阅UIAlertController)进行了有趣的更改,它们已从UIView/UIControls转换为UIViewControllers。
我应该注意一个UIViewController可能会在这里矫枉过正,因为我觉得popover会非常简单。不过,实施起来也很简单。
以下是我正在呈现的UIViewController的一些示例代码:
的SecondViewController是酥料饼:
#import "SecondViewController.h"
#import "SecondPresentationController.h"
@interface SecondViewController() <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
@property (nonatomic, getter=isPresenting) BOOL presenting;
@end
@implementation SecondViewController
#pragma mark - Initialization
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.transitioningDelegate = self;
self.modalPresentationStyle = UIModalPresentationCustom;
self.view.layer.cornerRadius = 5.0f;
self.view.clipsToBounds = YES;
}
return self;
}
#pragma mark - Content Size
- (CGSize)preferredContentSize {
return CGSizeMake(266.0f, 143.0f); // The static size of the test image I'm using for this sample code.
}
#pragma mark - UIViewControllerTransitioningDelegate
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 1.0;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
self.presenting = YES; /// Used in animateTransition
return self;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
self.presenting = NO; /// Used in animateTransition
return self;
}
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source {
return [[SecondPresentationController alloc] initWithPresentedViewController:self presentingViewController:self.presentingViewController];
}
#pragma mark - UIViewControllerAnimatedTransitioning
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
CGSize preferredSize = toViewController.preferredContentSize;
// onscreenFrame will be in the center of the superview, while offscreen will be just below the superview (and off of the screen completely)
CGRect onscreenFrame = CGRectMake((fromViewController.view.bounds.size.width - preferredSize.width) * 0.5f, (fromViewController.view.bounds.size.height - preferredSize.height) * 0.5f,
preferredSize.width, preferredSize.height);
CGRect offscreenFrame = onscreenFrame;
offscreenFrame.origin.y = fromViewController.view.bounds.size.height;
// Set the *initial* frame for the viewController.
if (self.isPresenting) {
toViewController.view.frame = offscreenFrame;
}
else {
toViewController.view.frame = onscreenFrame;
}
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.8f initialSpringVelocity:0.8f options:kNilOptions animations:^{
// Now animate to the final frame.
if (self.isPresenting) {
toViewController.view.frame = onscreenFrame;
}
else {
toViewController.view.frame = offscreenFrame;
}
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
@end
的SecondPresentationController处理curtainview:
#import "SecondPresentationController.h"
@interface SecondPresentationController()
@property (nonatomic, readonly) UIView *curtainView;
@end
@implementation SecondPresentationController
- (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController {
self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController];
if (self) {
_curtainView = [UIView new];
self.curtainView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.6f];
self.curtainView.alpha = 0.0f;
}
return self;
}
- (void)presentationTransitionWillBegin {
UIView *containerView = self.containerView;
self.curtainView.frame = containerView.bounds;
self.curtainView.alpha = 0.0f;
[containerView insertSubview:self.curtainView atIndex:0];
[self.presentedViewController.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
self.curtainView.alpha = 1.0f;
} completion:nil];
}
@end
然后,你会像平常一样呈现SecondViewController。
结果:
这当然不是一个UIView更复杂一点,但没有必要乱用应用程序的一个UIWindow,或要求一个UIWindow的RootViewController的我们酥料饼添加为子视图。如果您有任何问题,请告诉我。