Swift4.1 转场动画实现侧滑抽屉效果,支持转屏

这篇博客介绍了如何在Swift4.1中利用Modal转场动画创建侧滑抽屉效果,该效果支持屏幕旋转。通过使用SnapKit进行布局,确保动画在不同屏幕方向下正常工作。当手势速度超过300或进度达到30%,动画将完成;否则会回滚取消。实现过程中,主要涉及DrawerControl和Animator两个文件,前者用于控制抽屉的显示,后者处理动画及交互。抽屉展示时,主界面会显示遮罩层。
摘要由CSDN通过智能技术生成

实现使用了Modal转场动画,原因是项目多由导航控制器和标签控制器作为基类,为了不影响导航控制器的代理,转场动画使用模态交互。

 

代码使用SnapKit进行布局,能够适应屏幕旋转。手势速率大于300或进度超过30%的时候直接完成动画,否则动画回滚取消,具体数值可以修改对应的常量。抽屉出现的时候,主控制有遮罩,对应关键字是mask。

 

 

实现文件只有两个

DrawerControl:控制抽屉出现,一行代码即可调用

Animator:负责动画实现,包括了交互式的代理事件和非交互式的代理事件

//
//  DrawerControl.swift
//  PratiseSwift
//
//  Created by EugeneLaw on 2018/7/31.
//  Copyright © 2018年 EugeneLaw. All rights reserved.
//

import UIKit

enum DrawerSize {
    case Left
    case Right
}

class DrawerControl: NSObject {
    
    /**主页面*/
    var base: UIViewController?
    /**抽屉控制器*/
    var drawer: UIViewController?
    /**抽屉在左边还是右边,默认左边,没有实现右边,要右边自己去animator里面加判断*/
    var whichSize = DrawerSize.Left
    /**拖拽手势*/
    var panBase: UIPanGestureRecognizer?
    var panDrawer: UIPanGestureRecognizer?
    /**主页面在抽屉显示时保留的宽度*/
    var baseWidth: CGFloat {
        get {
            return self.animator!.baseWidth
        }
        set {
            self.animator?.baseWidth = newValue
        }
    }
    /**是否应该响应手势*/
    var shouldResponseRecognizer = false
    /**效果响应*/
    var animator: Animator?
    

    init(base: UIViewController, drawer: UIViewController) {
        super.init()
        self.base = base
        self.drawer = drawer
        animator = Animator(base: self.base!, drawer: self.drawer!)
        self.panBase = UIPanGestureRecognizer(target: self, action: #selector(panBaseAction(pan:)))
        base.view.addGestureRecognizer(self.panBase!)
        self.panDrawer = UIPanGestureRecognizer(target: self, action: #selector(panDrawerAction(pan:)))
        drawer.view.addGestureRecognizer(self.panDrawer!)
        self.drawer?.transitioningDelegate = self.animator
    }
    
    deinit {
        if self.panBase != nil {
            self.base?.view.removeGestureRecognizer(self.panBase!)
            self.panBase = nil
        }
        if self.panDrawer != nil {
            self.drawer?.view.removeGestureRecognizer(self.panDrawer!)
            self.panDrawer = nil
        }
    }
    
}

extension DrawerControl {
    
    ///显示抽屉
    func show() {
        if (self.base?.view.frame.origin.x)! > SCREEN_WIDTH/2 {
            return
        }
        self.animator?.interative = false
        self.base?.present(self.drawer!, animated: true, completion: nil)
    }
    
    ///关闭抽屉,或直接dismiss即可
    func close() {
        self.animator?.interative = false
        self.drawer?.dismiss(animated: true, completion: nil)
    }
    
}

extension DrawerControl {
    
    @objc func panBaseAction(pan: UIPanGestureRecognizer) {
        let transition = pan.translation(in: self.drawer?.view)
        let percentage = CGFloat(transition.x/SCREEN_WIDTH)
        let velocity = CGFloat(fabs(pan.velocity(in: self.drawer?.view).x))
        switch pan.state {
        case .began:
            if transition.x < 0 {
                shouldResponseRecognizer = false
            }else {
                shouldResponseRecognizer = true
            }
            if shouldResponseRecognizer {
                self.beginAnimator(showDrawer: true)
            }
        case .changed:
            if shouldRes
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EugeneLaw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值