2015-12-08 65 views
0

我正在研究实现如下图所示的自定义弹出对话框,并且遇到了各种方法来实现此目标。自定义弹出对话框

1-调用被定位这增加覆盖到当前视图层次结构和动画的方式向屏幕

2-使用UIPresentationController的中心这需要大量代码

屏幕的外部的 View

3使用pod

我想知道iOS中这种'弹出窗口的当前状态是什么,哪些是最简单和最直接的实现。

我正在寻找一个答案,彻底比较现有的选项,并清楚地展示每个的利弊。

enter image description here

回答

1

如果要支持的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。

结果:

The result after presenting the popup. 这当然不是一个UIView更复杂一点,但没有必要乱用应用程序的一个UIWindow,或要求一个UIWindow的RootViewController的我们酥料饼添加为子视图。如果您有任何问题,请告诉我。