Ios 自定义弹出对话框
我正在研究如何实现自定义弹出对话框,如下图所示,并遇到了实现这一目标的各种方法 1-调用位于屏幕外部的Ios 自定义弹出对话框,ios,cocoa-touch,uikit,Ios,Cocoa Touch,Uikit,我正在研究如何实现自定义弹出对话框,如下图所示,并遇到了实现这一目标的各种方法 1-调用位于屏幕外部的视图,该视图向当前视图层次结构添加覆盖,并以动画方式显示到屏幕中心 2-使用需要大量代码的UIPresentationController 3-使用吊舱 我想知道iOS中此类弹出窗口的当前状态,以及最简单和最直接的实现方式 我正在寻找一个答案,详尽地比较现有的选择,并清楚地表明每种选择的利弊 如果您支持iOS 8及以上版本(如果可能的话,您应该支持!),我建议使用UIViewController
视图
,该视图向当前视图层次结构添加覆盖,并以动画方式显示到屏幕中心
2-使用需要大量代码的UIPresentationController
3-使用吊舱
我想知道iOS中此类弹出窗口的当前状态,以及最简单和最直接的实现方式
我正在寻找一个答案,详尽地比较现有的选择,并清楚地表明每种选择的利弊
如果您支持iOS 8及以上版本(如果可能的话,您应该支持!),我建议使用UIViewController和UIPresentationController在后台处理窗帘视图 我的理由: •这两种API都是全新的100%原生API •苹果对其自己的一些API(请参阅UIAlertController)进行了有趣的更改,在这些API中,他们已从UIView/uicontrol转换到UIViewController 我应该注意到,UIViewController在这里可能有些过分,因为我觉得popover非常简单。不过,它的实现也非常简单 下面是我正在演示的UIViewController的一些示例代码: 第二个ViewController是popover:
#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
#导入“SecondViewController.h”
#导入“SecondPresentationController.h”
@接口SecondViewController()
@属性(非原子,getter=isPresenting)布尔呈现;
@结束
@第二视图控制器的实现
#pragma标记-初始化
-(instancetype)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil{
self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
如果(自我){
self.transitioningDelegate=self;
self.modalPresentationStyle=UIModalPresentationCustom;
self.view.layer.cornerRadius=5.0f;
self.view.clipstobunds=是;
}
回归自我;
}
#pragma标记-内容大小
-(CGSize)首选内容大小{
返回CGSizeMake(266.0f,143.0f);//我用于此示例代码的测试图像的静态大小。
}
#pragma标记-UIViewControllerTransitioningDelegate
-(NSTimeInterval)transitionDuration:(id)transitionContext{
返回1.0;
}
-(id)animationControllerForPresentedController:(UIViewController*)PresentedPresentingController:(UIViewController*)PresentingSourceController:(UIViewController*)源{
self.presenting=YES;///用于动画转换
回归自我;
}
-(id)animationControllerForDismissedController:(UIViewController*)已解除{
self.presenting=NO;///用于动画转换
回归自我;
}
-(UIPresentationController*)PresentationController for PresentedViewController:(UIViewController*)PresentedViewController:(UIViewController*)PresentedViewController:(UIViewController*)PresentedSourceViewController:(UIViewController*)源{
return[[Second PresentationController alloc]initWithPresentedViewController:self-presentingViewController:self.presentingViewController];
}
#pragma标记-UIViewControlleranimated转换
-(void)animateTransfion:(id)transitionContext{
UIViewController*fromViewController=[transitionContext ViewControllerWorky:UITransitionContextFromViewControllerKey];
UIViewController*toViewController=[transitionContext ViewControllerWorky:UITransitionContextToViewControllerKey];
[[transitionContext containerView]添加子视图:toViewController.view];
CGSize preferredSize=toViewController.preferredContentSize;
//屏幕上的画面将位于superview的中心,而屏幕外的画面将位于superview的正下方(并完全脱离屏幕)
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=在CREENFRAME上;
offscreenFrame.origin.y=fromViewController.view.bounds.size.height;
//设置viewController的*初始*帧。
如果(自我呈现){
toViewController.view.frame=Offscreen帧;
}
否则{
toViewController.view.frame=onscreenFrame;
}
[ui查看动画时长:0.5延迟:0.0使用带阻尼的弹簧:0.8f初始弹簧速度:0.8f选项:针织动画:^{
//现在设置动画到最后一帧。
如果(自我呈现){
toViewController.view.frame=onscreenFrame;
}
否则{
toViewController.view.frame=Offscreen帧;
}
}完成:^(布尔完成){
[transitionContext completeTransition:是];
}];
}
@结束
第二个PresentationController处理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
#导入“SecondPresentationController.h”
@接口SecondPresentationController()
@属性(非原子,只读)UIView*curtainView;
@结束
@第二个表示控制器的实现
-(instancetype)initWithPresentedViewController:(UIViewController*)presentedViewController presentingViewController:(UIViewController*)presentingViewController presentingViewController{
self=[super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController];
如果(自我){
_curtainView=[UIView新建];
self.curtainView.backgroundColor=[UIColor-WithWhite:0.0f alpha:0.6f];
self.curtainView.alpha=0.0f;
}
回归自我;
}
-(无效)表示转换将开始{
UIView*containerView=self.containerView;
self.curtainView.frame=containerView.bounds;
self.curtainView.alpha=0.0f;
[containerView insertSubview:self.curtainView索引:0];
[self.presentedViewController.transitionCoordinator AnimateLongsideTransition:^(id_非空上下文){
自己