自定义modal弹出样式(swift)

原创 2016年05月30日 18:46:04

0.假设vc是需要弹出的控制器(因为弹窗中有需要处理的事务,所以使用一个控制器管理)

1.弹出菜单(使用modal将对应的控制器弹出)

presentViewController(vc, animated: true, completion: nil)

2.如果想要自己决定弹出方式,需要成为其代理

vc.transitioningDelegate = self
vc.modalPresentationStyle = .Custom

3.实现transitioningDelegate的代理方法

//该代理方法用于返回负责转场的控制器对象
func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? {
   return PopoverPresentationController(presentedViewController: presented, presentingViewController: presenting)
    }
  //该代理方法用于告诉系统谁来负责控制器如何弹出
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
     //当弹窗要弹出的时候就会调用该方法
        return self
    }
    //该代理方法用于告诉系统谁来负责控制器如何消失
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
       //当弹窗要消失的时候就会调用该方法
        return self
    }

4.自定义显示和消失时弹窗展现方式

    // 该方法用于负责控制器如何弹出和如何消失
    // 只要是自定义转场, 控制器弹出和消失都会调用该方法
    // 需要在该方法中告诉系统控制器如何弹出和如何消失
    // 注意点: 但凡告诉系统我们需要自己来控制控制器的弹出和消失
    // 也就是实现了UIViewControllerAnimatedTransitioning的方法之后, 那么系统就不会再控制我们控制器的动画了, 所有的操作都需要我们自己完成
    // 系统调用该方法时会传递一个transitionContext参数, 该参数中包含了我们所有需要的值
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

        //在这里自定义出现和消失时的动画
    }

5.自定义蒙版

  • 注意点:
    所有被弹出的内容, 都是放在容器视图上的

  • 说明:因为当弹窗出现的时候,背后的控制器是不能处理事件的,所以将继承自 UIPresentationController的控制器(VC2)的containerView中添加一个UIBottom作为蒙版;

  • 因为UIBottom可以被监听,在VC2中监听蒙版,一旦点击,就是要消失弹窗;

  • 继承自UIPresentationController的控制器负责管理自定义转场动画
    在VC2中的 containerViewWillLayoutSubviews方法中设置弹窗的尺寸和位置,在 presentationTransitionWillBegin方法中添加蒙版,因为弹出的内容,都是放在容器视图中的,所以将蒙版添加到containerView中;在该方法中,containerView已经被创建;

6.设置显示时动画

因为显示和消失动画都是在第4步中的animateTransition方法中设置的,但是怎么区分是出现还是消失弹窗呢?

在第3步中,

func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
     //当弹窗要弹出的时候就会调用该方法
     isPresent = true
        return self
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
       //当弹窗要消失的时候就会调用该方法
     isPresent = false
        return self
 }

所以设置一个属性isPresent,当是弹出时,在animationControllerForPresentedController方法中设置为true;
如果是小数,在animationControllerForDismissedController中设置为false;这样在第4步中的animateTransition方法中设置动画则根据属性的值进行设置;

当isPresent = true 时:(抽取一个方法)

 /// 弹出动画
    private func animatePresentedController(transitionContext: UIViewControllerContextTransitioning) {
        // 0.获取动画时长
        let duration = transitionDuration(transitionContext)
                // 1.拿到被弹出的控制器的View
        guard let toView = transitionContext.viewForKey(UITransitionContextToViewKey) else {
            return
        }
        // 2.将被弹出的控制器View添加到容器视图上
        transitionContext.containerView()?.addSubview(toView)
        // 3.执行动画
        // 3.1先将菜单的View压扁
        toView.transform = CGAffineTransformMakeScale(1.0, 0.0)
        toView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
        // 3.2再清空菜单压扁的形变
        UIView.animateWithDuration(duration, animations: { () -> Void in
            toView.transform = CGAffineTransformIdentity
            }) { (_) -> Void in
                // 注意点: 但凡是自定义转场, 一定要在自定义动画完成之后告诉系统动画已经完成了, 否则会出现一些未知异常
                transitionContext.completeTransition(true)
        }
    }

7.设置消失动画

//动画消失
    private func animateDismissedController(transitionContext: UIViewControllerContextTransitioning) {

        // 0.获取动画时长
        let duration = transitionDuration(transitionContext)

        // 1.拿到菜单
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
        // 2.执行动画
        UIView.animateWithDuration(duration, animations: { () -> Void in
            // 注意; 没有动画的原因是MakeScale接收的是CGFloat, 而CGFloat得值是不准确的
            fromView?.transform = CGAffineTransformMakeScale(1.0, 0.0001)
            }) { (_) -> Void in
             transitionContext.completeTransition(true)
        }
  }
版权声明:本文为博主原创文章,未经博主允许不得转载。

Storyboard里面的几种Segue区别及视图的切换:push,modal,popover,replace和custom

一、视图切换类型介绍 在storyboard中,segue有几种不同的类型,在iphone和ipad的开发中,segue的类型是不同的。 在iphone中,segue有:push,moda...
  • xingxing513234072
  • xingxing513234072
  • 2014年05月11日 11:53
  • 11221

用Swift写一个IOS的自定义弹窗-纯代码实现

用Swift写一个IOS的自定义弹窗-纯代码实现   (在iOS代码库中浏览本帖) 关键字:弹出视图代码类库:弹出视图(PopupView)GitHub链接:https://github.c...
  • u014640208
  • u014640208
  • 2015年06月13日 11:16
  • 1559

Jquery浮动层插件modal(四种样式,附本人整理文档)

  • 2011年12月20日 12:39
  • 282KB
  • 下载

bootstrap2.3 与 bootstrap3.3 modal嵌入表单的样式改变

2014年12月16日22:55:24 我在做一个ssh的案例的时候,想做一个新增用户的模态框。我用bower下载的bootstrap应该是最新的3.31版本来的,在官网copy了一段模态框效果的原...
  • u012814005
  • u012814005
  • 2014年12月16日 22:55
  • 1616

swift 提示框

var alert = UIAlertView() alert.title = "Refresh?" alert.message = "All data[\(tvDat...
  • gishero
  • gishero
  • 2015年02月25日 22:45
  • 4570

Swift - 自定义UIAlertController的样式1(修改标题、按钮的字体和颜色)

自 iOS8 起,苹果把 UIActionSheet 和 UIAlertView 合并为了 UIAlertController。UIAlertController 的用法我之前也写过相关文章:Swif...
  • mo_xiao_mo
  • mo_xiao_mo
  • 2017年04月21日 09:21
  • 1950

ant design (antd) Modal 自定义样式,去除白色背景,边框,关闭按钮

想实现功能如下: 这个Modal没有头,没有确定什么的。 因为Modal组件不能自定义外边框,所以把所有的属性全都删掉之后: Modal title={null} visi...
  • wyk304443164
  • wyk304443164
  • 2017年03月30日 10:49
  • 6456

BootStrap一页通(样式+组件+插件)(全)

Bootstrap一页通(样式+组合+插件)(更新完毕)
  • sunxiaofre
  • sunxiaofre
  • 2017年03月17日 12:12
  • 3326

swift实现提示框第三方库:MBProgressHUD

GitHud的下载地址是:https://github.com/jdg/MBProgressHUD/ 下载完成后,将MBProgressHUD.h和MBProgressHUD.m拖入已经新建好的Sw...
  • walkerwqp
  • walkerwqp
  • 2017年01月12日 14:34
  • 1643

Swift 百度地图自定义弹出视图

// // MapViewController.swift // iOS8自适应Cell // // Created by eduo_xiaoP on 14/12/22. // Copyrig...
  • gxp1032901
  • gxp1032901
  • 2015年01月06日 17:02
  • 1183
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义modal弹出样式(swift)
举报原因:
原因补充:

(最多只允许输入30个字)