├── .gitignore ├── Classes ├── GYSide.swift ├── GYSideAnimatedTransitioning.swift ├── GYSideConfig.swift ├── GYSideMaskView.swift ├── GYSidePercentInteractiveTransition.swift └── GYSideTransitioningDelegate.swift ├── GYSide.podspec ├── GYSideDemo ├── GYSideDemo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── GYSideDemo.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── GYSideDemo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── LeftViewController.swift │ ├── PresentViewController.swift │ ├── RightViewController.swift │ ├── SceneDelegate.swift │ ├── ViewController.swift │ └── img │ │ ├── 1.jpeg │ │ ├── 2.jpeg │ │ ├── 3.jpeg │ │ └── 4.jpeg ├── GYSideDemoTests │ ├── GYSideDemoTests.swift │ └── Info.plist ├── GYSideDemoUITests │ ├── GYSideDemoUITests.swift │ └── Info.plist ├── Podfile └── Podfile.lock ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output 69 | 70 | -------------------------------------------------------------------------------- /Classes/GYSide.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSide.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | var showControlelrTransitioningDelegateKey = "showControlelrTransitioningDelegateKey" 12 | let GYSideTapNotification = "GYSideTapNotification" 13 | let GYSidePanNotification = "GYSidePanNotification" 14 | let kScreenWidth = UIScreen.main.bounds.width 15 | 16 | extension UIViewController { 17 | 18 | /// 侧边栏出来 19 | /// 20 | /// - Parameters: 21 | /// - configuration: 配置 22 | /// - viewController: 将要展现的viewController 23 | public func gy_showSide(_ configuration:(GYSideConfig)->(), _ viewController:UIViewController) { 24 | 25 | let config = GYSideConfig() 26 | configuration(config) 27 | 28 | var delegate = objc_getAssociatedObject(self, &showControlelrTransitioningDelegateKey) 29 | if delegate == nil { 30 | delegate = GYSideTransitioningDelegate(config) 31 | objc_setAssociatedObject(viewController, &showControlelrTransitioningDelegateKey, delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 32 | }else { 33 | let d = delegate as! GYSideTransitioningDelegate 34 | d.config = config 35 | } 36 | let d = delegate as! GYSideTransitioningDelegate 37 | let dismissalInteractiveTransition = GYSidePercentInteractiveTransition(showType: .hidden, viewController:viewController, config: config) 38 | d.dismissalInteractiveTransition = dismissalInteractiveTransition 39 | viewController.transitioningDelegate = delegate as? UIViewControllerTransitioningDelegate 40 | viewController.modalPresentationStyle = .fullScreen 41 | DispatchQueue.main.async { //防止present延迟 42 | self.present(viewController, animated: true, completion: nil) 43 | } 44 | } 45 | 46 | 47 | /// 让侧边栏支持手势拖拽出来 48 | /// 49 | /// - Parameter completeShowGesture: 侧边栏展示的方向 50 | public func gy_registGestureShowSide(completeShowGesture:@escaping (GYSideDirection)->()) { 51 | let delegate = GYSideTransitioningDelegate(nil) 52 | let presentationInteractiveTransition = GYSidePercentInteractiveTransition(showType: .show, viewController: nil, config: nil) 53 | presentationInteractiveTransition.addPanGesture(fromViewController: self) 54 | presentationInteractiveTransition.completeShowGesture = completeShowGesture 55 | delegate.presentationInteractiveTransition = presentationInteractiveTransition 56 | 57 | self.transitioningDelegate = delegate 58 | objc_setAssociatedObject(self, &showControlelrTransitioningDelegateKey, delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 59 | } 60 | 61 | public func gy_sidePushViewController(viewController: UIViewController) { 62 | let rootVC: UIViewController = (UIApplication.shared.keyWindow?.rootViewController)! 63 | var nav: UINavigationController? 64 | if rootVC is UITabBarController { 65 | let tabBar: UITabBarController = rootVC as! UITabBarController 66 | viewController.hidesBottomBarWhenPushed = true 67 | nav = tabBar.selectedViewController as? UINavigationController 68 | }else if rootVC is UINavigationController { 69 | nav = rootVC as? UINavigationController 70 | }else { 71 | fatalError("没有UINavigationController") 72 | } 73 | self.dismiss(animated: true, completion: nil) 74 | nav?.pushViewController(viewController, animated: false) 75 | } 76 | 77 | 78 | /// 侧边栏调用present 79 | /// 80 | /// - Parameter viewController 81 | public func gy_sidePresentViewController(viewController: UIViewController) { 82 | viewController.modalPresentationStyle = .fullScreen 83 | let rootVC: UIViewController = (UIApplication.shared.keyWindow?.rootViewController)! 84 | if ((rootVC.presentedViewController) != nil) { 85 | rootVC.presentedViewController?.dismiss(animated: true, completion: { 86 | DispatchQueue.main.async { 87 | rootVC.present(viewController, animated: true, completion: nil) 88 | } 89 | }) 90 | } 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /Classes/GYSideAnimatedTransitioning.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSideAnimatedTransitioning.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum GYSideShowType:Int { 12 | case show,hidden 13 | } 14 | 15 | class GYSideAnimatedTransitioning: NSObject,UIViewControllerAnimatedTransitioning { 16 | 17 | var type:GYSideShowType! 18 | var config:GYSideConfig! 19 | 20 | init(showType: GYSideShowType,config: GYSideConfig) { 21 | self.type = showType 22 | self.config = config 23 | } 24 | 25 | // 执行的动画时长 26 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 27 | config.timeInterval 28 | } 29 | 30 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 31 | switch type { 32 | case .show?: 33 | animateTransitionShowType(transitionContext: transitionContext) 34 | break 35 | case .hidden?: 36 | animateTransitionHiddenType(transitionContext: transitionContext) 37 | break 38 | default: 39 | break 40 | } 41 | } 42 | 43 | // show 44 | func animateTransitionShowType(transitionContext: UIViewControllerContextTransitioning) { 45 | let fromController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)! 46 | let toController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)! 47 | let containerView = transitionContext.containerView 48 | let width:CGFloat = (UIApplication.shared.keyWindow?.bounds.size.width)! * config.sideRelative 49 | let x:CGFloat! = config.direction == .left ? 0.0 : ((UIApplication.shared.keyWindow?.bounds.size.width)! - width) 50 | toController.view.frame = CGRect.init(x: x, y: 0, width: width, height: containerView.frame.height) 51 | toController.view.clipsToBounds = true 52 | // fromController UINavigationController 53 | // toController SnapKitViewController 54 | containerView.addSubview(toController.view) 55 | containerView.addSubview(fromController.view) 56 | 57 | var mask:GYSideMaskView? 58 | for view in toController.view.subviews where view is GYSideMaskView { 59 | mask = view as? GYSideMaskView 60 | } 61 | if mask == nil { 62 | mask = GYSideMaskView() 63 | fromController.view.addSubview(mask!) 64 | } 65 | mask?.frame = fromController.view.bounds 66 | mask?.alpha = 0.0 67 | mask?.isUserInteractionEnabled = false 68 | 69 | let flag: CGFloat! = config.direction == .left ? -1.0 : 1.0 70 | 71 | var fromTransform: CGAffineTransform = CGAffineTransform(translationX: -flag * width, y: 0) 72 | let toTransform: CGAffineTransform = CGAffineTransform(translationX: flag * width, y: 0) 73 | 74 | if self.config.animationType == .translationMask { 75 | fromTransform = CGAffineTransform(translationX: 0, y: 0) 76 | containerView.bringSubviewToFront(toController.view) 77 | }else if self.config.animationType == .zoom { 78 | let t1: CGAffineTransform = CGAffineTransform(translationX: -flag * width * config.zoomOffsetRelative, y: 0) 79 | let t2: CGAffineTransform = CGAffineTransform(scaleX: config.zoomRelative, y: config.zoomRelative) 80 | fromTransform = t1.concatenating(t2) 81 | } 82 | if self.config.animationType != .zoom { 83 | toController.view.transform = toTransform 84 | toController.view.frame = CGRect(x: toTransform.tx+x, y: 0, width: width, height: containerView.frame.height) 85 | }else { 86 | toController.view.transform = CGAffineTransform(translationX: 0, y: 0) 87 | toController.view.frame = CGRect(x: 0, y: 0, width: width, height: containerView.frame.height) 88 | } 89 | 90 | UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: { 91 | mask?.alpha = self.config.maskAlpha 92 | toController.view.transform = .identity 93 | fromController.view.transform = fromTransform 94 | }) { (finished) in 95 | if !transitionContext.transitionWasCancelled { 96 | mask?.isUserInteractionEnabled = true 97 | transitionContext.completeTransition(true) 98 | containerView.addSubview(fromController.view) 99 | if self.config.animationType == .translationMask { 100 | containerView.bringSubviewToFront(toController.view) 101 | } 102 | }else { 103 | mask?.destroy() 104 | toController.view.transform = toTransform; 105 | fromController.view.frame = containerView.frame; 106 | transitionContext.completeTransition(false) 107 | } 108 | } 109 | } 110 | 111 | 112 | // hidde 113 | func animateTransitionHiddenType(transitionContext: UIViewControllerContextTransitioning) { 114 | let fromController:UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)! 115 | let toController:UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)! 116 | 117 | let containerView = transitionContext.containerView 118 | let width:CGFloat = (UIApplication.shared.keyWindow?.bounds.size.width)! * self.config.sideRelative 119 | let x:CGFloat! = config.direction == .left ? 0.0 : ((UIApplication.shared.keyWindow?.bounds.size.width)! - width) 120 | 121 | fromController.view.frame = CGRect.init(x: x, y: 0, width: width, height: containerView.frame.height) 122 | 123 | var mask:GYSideMaskView? 124 | for view in toController.view.subviews { 125 | if view.isKind(of: GYSideMaskView.classForCoder()){ 126 | mask = view as? GYSideMaskView 127 | break 128 | } 129 | } 130 | 131 | let flag: CGFloat! = config.direction == GYSideDirection.left ? -1.0 : 1.0 132 | var fromTransform:CGAffineTransform = CGAffineTransform.init(translationX: flag * width, y: 0) 133 | 134 | if self.config.animationType == .translationMask { 135 | fromTransform = CGAffineTransform.init(translationX: flag * width, y: 0) 136 | }else if self.config.animationType == .zoom { 137 | fromTransform = CGAffineTransform.init(translationX: 0, y: 0) 138 | containerView.bringSubviewToFront(toController.view) 139 | } 140 | 141 | UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: { 142 | mask?.alpha = 0.001 143 | fromController.view.transform = fromTransform 144 | toController.view.transform = .identity 145 | }) { (finished) in 146 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 147 | if !transitionContext.transitionWasCancelled { 148 | mask?.destroy() 149 | }else { 150 | if self.config.animationType != .zoom { 151 | containerView.bringSubviewToFront(fromController.view) 152 | } 153 | } 154 | } 155 | } 156 | 157 | deinit { 158 | // print( NSStringFromClass(self.classForCoder) + " 销毁了---->4") 159 | } 160 | } 161 | 162 | -------------------------------------------------------------------------------- /Classes/GYSideConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSideConfig.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum GYSideAnimationType:Int { 12 | case zoom //缩放 13 | case translationPush //横向平移 14 | case translationMask //盖在最上面横向平移 15 | } 16 | 17 | public enum GYSideDirection:Int { 18 | case left // 从左边出来 19 | case right // 从右边出来 20 | } 21 | 22 | public class GYSideConfig { 23 | 24 | /// 执行动画的时长 默认0.3 25 | public var timeInterval: TimeInterval! = 0.3 26 | 27 | /// 遮罩视图的透明度 默认0.5 28 | public var maskAlpha: CGFloat! = 0.5 29 | 30 | /// 侧边栏相对屏幕宽度比例 0.0 ~ 1.0 默认0.7 31 | public var sideRelative: CGFloat! = 0.7 { 32 | didSet { 33 | if sideRelative>1.0 {sideRelative = 1.0} 34 | if sideRelative<0.0 {sideRelative = 0.0} 35 | if animationType == .zoom {sideRelative = 1.0} 36 | } 37 | } 38 | 39 | /// 缩放模式时缩放的比例 0.0 ~ 1.0 默认0.7 40 | public var zoomRelative: CGFloat! = 0.7 { 41 | didSet { 42 | if zoomRelative>1.0 {zoomRelative = 1.0} 43 | if zoomRelative<0.0 {zoomRelative = 0.0} 44 | } 45 | } 46 | 47 | /// 缩放模式时 缩放控制器的view偏移的距离 相对屏幕宽度比例 0.0 ~ 1.0 默认0.5 48 | public var zoomOffsetRelative: CGFloat! = 0.5 { 49 | didSet { 50 | if zoomOffsetRelative>1.0 {zoomOffsetRelative = 1.0} 51 | if zoomOffsetRelative<0.0 {zoomOffsetRelative = 0.0} 52 | } 53 | } 54 | 55 | /// 侧边来出来的的方向 默认从左边出来 56 | public var direction:GYSideDirection! = .left 57 | 58 | /// 侧边来出来的动画方式 59 | public var animationType:GYSideAnimationType! = .translationPush { 60 | didSet { 61 | if animationType == .zoom {sideRelative = 1.0} 62 | } 63 | } 64 | 65 | deinit { 66 | // print( NSStringFromClass(self.classForCoder) + " 销毁了---->1") 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /Classes/GYSideMaskView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSideMaskView.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class GYSideMaskView: UIVisualEffectView { 12 | 13 | init() { 14 | super.init(effect: UIBlurEffect.init(style: .dark)) 15 | //初始准备代码 16 | let tap: UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(tapAction(_ :))) 17 | self.addGestureRecognizer(tap) 18 | 19 | let pan: UIPanGestureRecognizer = UIPanGestureRecognizer.init(target: self, action: #selector(panAction(_ :))) 20 | self.addGestureRecognizer(pan) 21 | } 22 | 23 | required init?(coder aDecoder: NSCoder) { 24 | fatalError("init(coder:) has not been implemented") 25 | } 26 | 27 | 28 | @objc private func tapAction(_ sender:UITapGestureRecognizer) { 29 | NotificationCenter.default.post(name: NSNotification.Name(rawValue:GYSideTapNotification), object: nil) 30 | } 31 | 32 | @objc private func panAction(_ sender:UITapGestureRecognizer) { 33 | NotificationCenter.default.post(name: NSNotification.Name(rawValue:GYSidePanNotification), object: sender) 34 | } 35 | 36 | func destroy() { 37 | self.removeFromSuperview() 38 | } 39 | 40 | deinit { 41 | // print( NSStringFromClass(self.classForCoder) + " 销毁了---->2") 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Classes/GYSidePercentInteractiveTransition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSidePercentInteractiveTransition.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | typealias completeShowGestureTask = (GYSideDirection) -> () 12 | 13 | class GYSidePercentInteractiveTransition: UIPercentDrivenInteractiveTransition { 14 | 15 | var completeShowGesture:completeShowGestureTask? 16 | var isInteractive:Bool! = false 17 | weak var _targetVC:UIViewController! 18 | var _config:GYSideConfig! 19 | var _showType:GYSideShowType! 20 | private var _direction:GYSideDirection? 21 | private var _percent:CGFloat = 0.0 //必须用全局的 22 | 23 | init(showType:GYSideShowType,viewController:UIViewController?,config:GYSideConfig?) { 24 | super.init() 25 | _showType = showType 26 | _targetVC = viewController 27 | _config = config 28 | NotificationCenter.default.addObserver(self, selector: #selector(gy_tapAction), name: NSNotification.Name(rawValue:GYSideTapNotification), object: nil) 29 | NotificationCenter.default.addObserver(self, selector: #selector(gy_panAction(_ :)), name: NSNotification.Name(rawValue:GYSidePanNotification), object: nil) 30 | } 31 | 32 | @objc func gy_tapAction() { 33 | if _showType == .show {return} 34 | _targetVC?.dismiss(animated: true, completion: nil) 35 | finish() 36 | } 37 | 38 | @objc func gy_panAction(_ sender:Notification) { 39 | let pan:UIPanGestureRecognizer = sender.object as! UIPanGestureRecognizer 40 | if _showType == .hidden { 41 | handlePan(pan: pan) 42 | } 43 | } 44 | 45 | func addPanGesture(fromViewController:UIViewController) { 46 | let pan:UIPanGestureRecognizer = UIPanGestureRecognizer.init(target: self, action: #selector(handlePan(pan:))) 47 | fromViewController.view.addGestureRecognizer(pan) 48 | } 49 | 50 | //手势blcok 回调 51 | func handlePresentPan(pan:UIPanGestureRecognizer) { 52 | var x:CGFloat = pan.translation(in: pan.view).x // -左划 +右滑 53 | let width:CGFloat = (pan.view!.bounds.width) 54 | var percent:CGFloat = 0.0 55 | 56 | switch pan.state { 57 | case .began: 58 | if x<0 { 59 | _direction = .right; 60 | }else if x>=0 { 61 | _direction = .left; 62 | } 63 | isInteractive = true 64 | if (completeShowGesture != nil) { 65 | completeShowGesture!(_direction!) 66 | } 67 | break 68 | case .changed: 69 | if _direction == GYSideDirection.right { 70 | x = x>0.0 ? 0.0:x; 71 | }else { 72 | x = x<0.0 ? 0.0:x; 73 | } 74 | percent = CGFloat(fabsf(Float(x/width))) 75 | percent = percent<=0.0 ? 0.0:percent 76 | percent = percent>=1.0 ? 1.0:percent 77 | _percent = percent 78 | self.update(percent) 79 | break 80 | case .ended: 81 | isInteractive = false 82 | if _percent < 0.5 { 83 | cancel() 84 | }else { 85 | finish() 86 | } 87 | break 88 | case .cancelled: 89 | isInteractive = false 90 | cancel() 91 | break 92 | default: 93 | break 94 | } 95 | } 96 | 97 | @objc func handlePan(pan: UIPanGestureRecognizer) { 98 | var x:CGFloat = pan.translation(in: pan.view).x // -左划 +右滑 99 | if _config == nil && _showType == .show{ 100 | handlePresentPan(pan: pan) 101 | return 102 | } 103 | var width:CGFloat = (pan.view!.bounds.width) // 手势驱动时 相对移动的宽度 104 | if _config.animationType == .zoom { 105 | width = kScreenWidth*(1.0 - _config.zoomOffsetRelative) 106 | } 107 | var percent:CGFloat = 0.0 108 | switch pan.state { 109 | case .began : 110 | isInteractive = true 111 | _targetVC.dismiss(animated: true, completion: nil) 112 | break; 113 | case .changed: 114 | if _config.direction == GYSideDirection.left && _showType == .hidden { 115 | x = x>0.0 ? 0.0:x 116 | }else { 117 | x = x<0.0 ? 0.0:x 118 | } 119 | percent = CGFloat(fabsf(Float(x/width))) 120 | percent = percent<=0.0 ? 0.0:percent 121 | percent = percent>=1.0 ? 1.0:percent 122 | _percent = percent 123 | update(percent) 124 | break 125 | case .ended: 126 | isInteractive = false 127 | if _percent < 0.5 { 128 | cancel() 129 | }else { 130 | finish() 131 | } 132 | break 133 | case .cancelled: 134 | isInteractive = false 135 | cancel() 136 | break 137 | default: 138 | break 139 | } 140 | } 141 | 142 | deinit { 143 | NotificationCenter.default.removeObserver(self) 144 | // print( NSStringFromClass(self.classForCoder) + " 销毁了---->5") 145 | } 146 | 147 | } 148 | 149 | -------------------------------------------------------------------------------- /Classes/GYSideTransitioningDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSideTransitioningDelegate.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class GYSideTransitioningDelegate: NSObject,UIViewControllerTransitioningDelegate { 12 | 13 | var presentationInteractiveTransition: GYSidePercentInteractiveTransition? 14 | var dismissalInteractiveTransition: GYSidePercentInteractiveTransition! 15 | var config: GYSideConfig! 16 | 17 | init(_ config:GYSideConfig?) { 18 | self.config = config 19 | } 20 | 21 | func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 22 | GYSideAnimatedTransitioning(showType: .show, config: config) 23 | } 24 | 25 | func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 26 | GYSideAnimatedTransitioning(showType: .hidden, config: config) 27 | } 28 | 29 | // present交互的百分比 30 | func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 31 | if presentationInteractiveTransition == nil { 32 | return nil 33 | }else { 34 | return (presentationInteractiveTransition?.isInteractive)! ? presentationInteractiveTransition : nil 35 | } 36 | } 37 | 38 | // dismiss交互的百分比 39 | func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 40 | return dismissalInteractiveTransition.isInteractive ? dismissalInteractiveTransition : nil 41 | } 42 | deinit { 43 | // print( NSStringFromClass(self.classForCoder) + " 销毁了---->3") 44 | } 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /GYSide.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint GYSide.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "GYSide" 19 | s.version = "0.0.5" 20 | s.summary = "A swift viewController extension ." 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | 一个swift版的让控制器具有以侧面平移或者缩放展示菜单控制器的扩展库,菜单控制器在隐藏的时候会销毁,不会常驻在内存 29 | DESC 30 | 31 | s.homepage = "https://github.com/yuan-gao/GYSide" 32 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See http://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | s.license = "MIT" 43 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | s.author = { "gaoyuan" => "2502905737@qq.com" } 57 | # Or just: s.author = "gaoyuan" 58 | # s.authors = { "gaoyuan" => "2502905737@qq.com" } 59 | # s.social_media_url = "http://twitter.com/gaoyuan" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | # s.platform = :ios 68 | s.platform = :ios, "8.0" 69 | s.swift_versions = '5.0' 70 | 71 | # When using multiple platforms 72 | # s.ios.deployment_target = "5.0" 73 | # s.osx.deployment_target = "10.7" 74 | # s.watchos.deployment_target = "2.0" 75 | # s.tvos.deployment_target = "9.0" 76 | 77 | 78 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 79 | # 80 | # Specify the location from where the source should be retrieved. 81 | # Supports git, hg, bzr, svn and HTTP. 82 | # 83 | 84 | s.source = { :git => "https://github.com/yuan-gao/GYSide.git", :tag => "#{s.version}" } 85 | 86 | 87 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 88 | # 89 | # CocoaPods is smart about how it includes source code. For source files 90 | # giving a folder will include any swift, h, m, mm, c & cpp files. 91 | # For header files it will include any header in the folder. 92 | # Not including the public_header_files will make all headers public. 93 | # 94 | 95 | #s.source_files = "Classes", "Classes/**/*.{h,m}" 96 | #s.exclude_files = "Classes/Exclude" 97 | s.source_files = "Classes/*.swift" 98 | 99 | # s.public_header_files = "Classes/**/*.h" 100 | 101 | 102 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 103 | # 104 | # A list of resources included with the Pod. These are copied into the 105 | # target bundle with a build phase script. Anything else will be cleaned. 106 | # You can preserve files from being cleaned, please don't preserve 107 | # non-essential files like tests, examples and documentation. 108 | # 109 | 110 | # s.resource = "icon.png" 111 | # s.resources = "Resources/*.png" 112 | 113 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 114 | 115 | 116 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 117 | # 118 | # Link your library with frameworks, or libraries. Libraries do not include 119 | # the lib prefix of their name. 120 | # 121 | 122 | #s.framework = "UIKit" 123 | s.frameworks = "UIKit", "Foundation" 124 | 125 | # s.library = "iconv" 126 | # s.libraries = "iconv", "xml2" 127 | 128 | 129 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 130 | # 131 | # If your library depends on compiler flags you can set them in the xcconfig hash 132 | # where they will only apply to your library. If you depend on other Podspecs 133 | # you can include multiple dependencies to ensure it works. 134 | 135 | # s.requires_arc = true 136 | 137 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 138 | # s.dependency "JSONKit", "~> 1.4" 139 | 140 | end 141 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 18BDE1A51D9FBCBC37CA9BF1 /* libPods-GYSideDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A9D6087C2FC28FA60D3513 /* libPods-GYSideDemo.a */; }; 11 | D8909E7825E005D500DD6C28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909E7725E005D500DD6C28 /* AppDelegate.swift */; }; 12 | D8909E7A25E005D500DD6C28 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909E7925E005D500DD6C28 /* SceneDelegate.swift */; }; 13 | D8909E7C25E005D500DD6C28 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909E7B25E005D500DD6C28 /* ViewController.swift */; }; 14 | D8909E7F25E005D500DD6C28 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D8909E7D25E005D500DD6C28 /* Main.storyboard */; }; 15 | D8909E8125E005D900DD6C28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D8909E8025E005D900DD6C28 /* Assets.xcassets */; }; 16 | D8909E8425E005D900DD6C28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D8909E8225E005D900DD6C28 /* LaunchScreen.storyboard */; }; 17 | D8909E8F25E005D900DD6C28 /* GYSideDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909E8E25E005D900DD6C28 /* GYSideDemoTests.swift */; }; 18 | D8909E9A25E005D900DD6C28 /* GYSideDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909E9925E005D900DD6C28 /* GYSideDemoUITests.swift */; }; 19 | D8909EB125E006A100DD6C28 /* 1.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = D8909EAD25E006A100DD6C28 /* 1.jpeg */; }; 20 | D8909EB225E006A100DD6C28 /* 4.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = D8909EAE25E006A100DD6C28 /* 4.jpeg */; }; 21 | D8909EB325E006A100DD6C28 /* 2.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = D8909EAF25E006A100DD6C28 /* 2.jpeg */; }; 22 | D8909EB425E006A100DD6C28 /* 3.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = D8909EB025E006A100DD6C28 /* 3.jpeg */; }; 23 | D8909EBB25E006AA00DD6C28 /* PresentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909EB825E006AA00DD6C28 /* PresentViewController.swift */; }; 24 | D8909EBC25E006AA00DD6C28 /* LeftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909EB925E006AA00DD6C28 /* LeftViewController.swift */; }; 25 | D8909EBD25E006AA00DD6C28 /* RightViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8909EBA25E006AA00DD6C28 /* RightViewController.swift */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | D8909E8B25E005D900DD6C28 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = D8909E6C25E005D500DD6C28 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = D8909E7325E005D500DD6C28; 34 | remoteInfo = GYSideDemo; 35 | }; 36 | D8909E9625E005D900DD6C28 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = D8909E6C25E005D500DD6C28 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = D8909E7325E005D500DD6C28; 41 | remoteInfo = GYSideDemo; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 03A9D6087C2FC28FA60D3513 /* libPods-GYSideDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GYSideDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 2815CA7619E4118980D24C0F /* Pods-GYSideDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GYSideDemo.release.xcconfig"; path = "Target Support Files/Pods-GYSideDemo/Pods-GYSideDemo.release.xcconfig"; sourceTree = ""; }; 48 | 3F22BF64783115265BC939F1 /* Pods-GYSideDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GYSideDemo.debug.xcconfig"; path = "Target Support Files/Pods-GYSideDemo/Pods-GYSideDemo.debug.xcconfig"; sourceTree = ""; }; 49 | D8909E7425E005D500DD6C28 /* GYSideDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GYSideDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | D8909E7725E005D500DD6C28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 51 | D8909E7925E005D500DD6C28 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 52 | D8909E7B25E005D500DD6C28 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 53 | D8909E7E25E005D500DD6C28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 54 | D8909E8025E005D900DD6C28 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 55 | D8909E8325E005D900DD6C28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 56 | D8909E8525E005D900DD6C28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | D8909E8A25E005D900DD6C28 /* GYSideDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GYSideDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | D8909E8E25E005D900DD6C28 /* GYSideDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GYSideDemoTests.swift; sourceTree = ""; }; 59 | D8909E9025E005D900DD6C28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | D8909E9525E005D900DD6C28 /* GYSideDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GYSideDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | D8909E9925E005D900DD6C28 /* GYSideDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GYSideDemoUITests.swift; sourceTree = ""; }; 62 | D8909E9B25E005D900DD6C28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | D8909EAD25E006A100DD6C28 /* 1.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 1.jpeg; sourceTree = ""; }; 64 | D8909EAE25E006A100DD6C28 /* 4.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 4.jpeg; sourceTree = ""; }; 65 | D8909EAF25E006A100DD6C28 /* 2.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 2.jpeg; sourceTree = ""; }; 66 | D8909EB025E006A100DD6C28 /* 3.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 3.jpeg; sourceTree = ""; }; 67 | D8909EB825E006AA00DD6C28 /* PresentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentViewController.swift; sourceTree = ""; }; 68 | D8909EB925E006AA00DD6C28 /* LeftViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftViewController.swift; sourceTree = ""; }; 69 | D8909EBA25E006AA00DD6C28 /* RightViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RightViewController.swift; sourceTree = ""; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | D8909E7125E005D500DD6C28 /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | 18BDE1A51D9FBCBC37CA9BF1 /* libPods-GYSideDemo.a in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | D8909E8725E005D900DD6C28 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | D8909E9225E005D900DD6C28 /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 2908F0619F117C02A36E95A1 /* Pods */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 3F22BF64783115265BC939F1 /* Pods-GYSideDemo.debug.xcconfig */, 102 | 2815CA7619E4118980D24C0F /* Pods-GYSideDemo.release.xcconfig */, 103 | ); 104 | path = Pods; 105 | sourceTree = ""; 106 | }; 107 | B55B744B13B4F0EA9CB5A620 /* Frameworks */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 03A9D6087C2FC28FA60D3513 /* libPods-GYSideDemo.a */, 111 | ); 112 | name = Frameworks; 113 | sourceTree = ""; 114 | }; 115 | D8909E6B25E005D500DD6C28 = { 116 | isa = PBXGroup; 117 | children = ( 118 | D8909E7625E005D500DD6C28 /* GYSideDemo */, 119 | D8909E8D25E005D900DD6C28 /* GYSideDemoTests */, 120 | D8909E9825E005D900DD6C28 /* GYSideDemoUITests */, 121 | D8909E7525E005D500DD6C28 /* Products */, 122 | 2908F0619F117C02A36E95A1 /* Pods */, 123 | B55B744B13B4F0EA9CB5A620 /* Frameworks */, 124 | ); 125 | sourceTree = ""; 126 | }; 127 | D8909E7525E005D500DD6C28 /* Products */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | D8909E7425E005D500DD6C28 /* GYSideDemo.app */, 131 | D8909E8A25E005D900DD6C28 /* GYSideDemoTests.xctest */, 132 | D8909E9525E005D900DD6C28 /* GYSideDemoUITests.xctest */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | D8909E7625E005D500DD6C28 /* GYSideDemo */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | D8909EAC25E006A100DD6C28 /* img */, 141 | D8909E7725E005D500DD6C28 /* AppDelegate.swift */, 142 | D8909E7925E005D500DD6C28 /* SceneDelegate.swift */, 143 | D8909E7B25E005D500DD6C28 /* ViewController.swift */, 144 | D8909EB925E006AA00DD6C28 /* LeftViewController.swift */, 145 | D8909EB825E006AA00DD6C28 /* PresentViewController.swift */, 146 | D8909EBA25E006AA00DD6C28 /* RightViewController.swift */, 147 | D8909E7D25E005D500DD6C28 /* Main.storyboard */, 148 | D8909E8025E005D900DD6C28 /* Assets.xcassets */, 149 | D8909E8225E005D900DD6C28 /* LaunchScreen.storyboard */, 150 | D8909E8525E005D900DD6C28 /* Info.plist */, 151 | ); 152 | path = GYSideDemo; 153 | sourceTree = ""; 154 | }; 155 | D8909E8D25E005D900DD6C28 /* GYSideDemoTests */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | D8909E8E25E005D900DD6C28 /* GYSideDemoTests.swift */, 159 | D8909E9025E005D900DD6C28 /* Info.plist */, 160 | ); 161 | path = GYSideDemoTests; 162 | sourceTree = ""; 163 | }; 164 | D8909E9825E005D900DD6C28 /* GYSideDemoUITests */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | D8909E9925E005D900DD6C28 /* GYSideDemoUITests.swift */, 168 | D8909E9B25E005D900DD6C28 /* Info.plist */, 169 | ); 170 | path = GYSideDemoUITests; 171 | sourceTree = ""; 172 | }; 173 | D8909EAC25E006A100DD6C28 /* img */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | D8909EAD25E006A100DD6C28 /* 1.jpeg */, 177 | D8909EAE25E006A100DD6C28 /* 4.jpeg */, 178 | D8909EAF25E006A100DD6C28 /* 2.jpeg */, 179 | D8909EB025E006A100DD6C28 /* 3.jpeg */, 180 | ); 181 | path = img; 182 | sourceTree = ""; 183 | }; 184 | /* End PBXGroup section */ 185 | 186 | /* Begin PBXNativeTarget section */ 187 | D8909E7325E005D500DD6C28 /* GYSideDemo */ = { 188 | isa = PBXNativeTarget; 189 | buildConfigurationList = D8909E9E25E005D900DD6C28 /* Build configuration list for PBXNativeTarget "GYSideDemo" */; 190 | buildPhases = ( 191 | 12B854E1E517A031C765420B /* [CP] Check Pods Manifest.lock */, 192 | D8909E7025E005D500DD6C28 /* Sources */, 193 | D8909E7125E005D500DD6C28 /* Frameworks */, 194 | D8909E7225E005D500DD6C28 /* Resources */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | ); 200 | name = GYSideDemo; 201 | productName = GYSideDemo; 202 | productReference = D8909E7425E005D500DD6C28 /* GYSideDemo.app */; 203 | productType = "com.apple.product-type.application"; 204 | }; 205 | D8909E8925E005D900DD6C28 /* GYSideDemoTests */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = D8909EA125E005D900DD6C28 /* Build configuration list for PBXNativeTarget "GYSideDemoTests" */; 208 | buildPhases = ( 209 | D8909E8625E005D900DD6C28 /* Sources */, 210 | D8909E8725E005D900DD6C28 /* Frameworks */, 211 | D8909E8825E005D900DD6C28 /* Resources */, 212 | ); 213 | buildRules = ( 214 | ); 215 | dependencies = ( 216 | D8909E8C25E005D900DD6C28 /* PBXTargetDependency */, 217 | ); 218 | name = GYSideDemoTests; 219 | productName = GYSideDemoTests; 220 | productReference = D8909E8A25E005D900DD6C28 /* GYSideDemoTests.xctest */; 221 | productType = "com.apple.product-type.bundle.unit-test"; 222 | }; 223 | D8909E9425E005D900DD6C28 /* GYSideDemoUITests */ = { 224 | isa = PBXNativeTarget; 225 | buildConfigurationList = D8909EA425E005D900DD6C28 /* Build configuration list for PBXNativeTarget "GYSideDemoUITests" */; 226 | buildPhases = ( 227 | D8909E9125E005D900DD6C28 /* Sources */, 228 | D8909E9225E005D900DD6C28 /* Frameworks */, 229 | D8909E9325E005D900DD6C28 /* Resources */, 230 | ); 231 | buildRules = ( 232 | ); 233 | dependencies = ( 234 | D8909E9725E005D900DD6C28 /* PBXTargetDependency */, 235 | ); 236 | name = GYSideDemoUITests; 237 | productName = GYSideDemoUITests; 238 | productReference = D8909E9525E005D900DD6C28 /* GYSideDemoUITests.xctest */; 239 | productType = "com.apple.product-type.bundle.ui-testing"; 240 | }; 241 | /* End PBXNativeTarget section */ 242 | 243 | /* Begin PBXProject section */ 244 | D8909E6C25E005D500DD6C28 /* Project object */ = { 245 | isa = PBXProject; 246 | attributes = { 247 | LastSwiftUpdateCheck = 1200; 248 | LastUpgradeCheck = 1200; 249 | TargetAttributes = { 250 | D8909E7325E005D500DD6C28 = { 251 | CreatedOnToolsVersion = 12.0; 252 | }; 253 | D8909E8925E005D900DD6C28 = { 254 | CreatedOnToolsVersion = 12.0; 255 | TestTargetID = D8909E7325E005D500DD6C28; 256 | }; 257 | D8909E9425E005D900DD6C28 = { 258 | CreatedOnToolsVersion = 12.0; 259 | TestTargetID = D8909E7325E005D500DD6C28; 260 | }; 261 | }; 262 | }; 263 | buildConfigurationList = D8909E6F25E005D500DD6C28 /* Build configuration list for PBXProject "GYSideDemo" */; 264 | compatibilityVersion = "Xcode 9.3"; 265 | developmentRegion = en; 266 | hasScannedForEncodings = 0; 267 | knownRegions = ( 268 | en, 269 | Base, 270 | ); 271 | mainGroup = D8909E6B25E005D500DD6C28; 272 | productRefGroup = D8909E7525E005D500DD6C28 /* Products */; 273 | projectDirPath = ""; 274 | projectRoot = ""; 275 | targets = ( 276 | D8909E7325E005D500DD6C28 /* GYSideDemo */, 277 | D8909E8925E005D900DD6C28 /* GYSideDemoTests */, 278 | D8909E9425E005D900DD6C28 /* GYSideDemoUITests */, 279 | ); 280 | }; 281 | /* End PBXProject section */ 282 | 283 | /* Begin PBXResourcesBuildPhase section */ 284 | D8909E7225E005D500DD6C28 /* Resources */ = { 285 | isa = PBXResourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | D8909EB225E006A100DD6C28 /* 4.jpeg in Resources */, 289 | D8909E8425E005D900DD6C28 /* LaunchScreen.storyboard in Resources */, 290 | D8909EB325E006A100DD6C28 /* 2.jpeg in Resources */, 291 | D8909E8125E005D900DD6C28 /* Assets.xcassets in Resources */, 292 | D8909E7F25E005D500DD6C28 /* Main.storyboard in Resources */, 293 | D8909EB425E006A100DD6C28 /* 3.jpeg in Resources */, 294 | D8909EB125E006A100DD6C28 /* 1.jpeg in Resources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | D8909E8825E005D900DD6C28 /* Resources */ = { 299 | isa = PBXResourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | D8909E9325E005D900DD6C28 /* Resources */ = { 306 | isa = PBXResourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | ); 310 | runOnlyForDeploymentPostprocessing = 0; 311 | }; 312 | /* End PBXResourcesBuildPhase section */ 313 | 314 | /* Begin PBXShellScriptBuildPhase section */ 315 | 12B854E1E517A031C765420B /* [CP] Check Pods Manifest.lock */ = { 316 | isa = PBXShellScriptBuildPhase; 317 | buildActionMask = 2147483647; 318 | files = ( 319 | ); 320 | inputFileListPaths = ( 321 | ); 322 | inputPaths = ( 323 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 324 | "${PODS_ROOT}/Manifest.lock", 325 | ); 326 | name = "[CP] Check Pods Manifest.lock"; 327 | outputFileListPaths = ( 328 | ); 329 | outputPaths = ( 330 | "$(DERIVED_FILE_DIR)/Pods-GYSideDemo-checkManifestLockResult.txt", 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | shellPath = /bin/sh; 334 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 335 | showEnvVarsInLog = 0; 336 | }; 337 | /* End PBXShellScriptBuildPhase section */ 338 | 339 | /* Begin PBXSourcesBuildPhase section */ 340 | D8909E7025E005D500DD6C28 /* Sources */ = { 341 | isa = PBXSourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | D8909E7C25E005D500DD6C28 /* ViewController.swift in Sources */, 345 | D8909E7825E005D500DD6C28 /* AppDelegate.swift in Sources */, 346 | D8909EBB25E006AA00DD6C28 /* PresentViewController.swift in Sources */, 347 | D8909EBC25E006AA00DD6C28 /* LeftViewController.swift in Sources */, 348 | D8909E7A25E005D500DD6C28 /* SceneDelegate.swift in Sources */, 349 | D8909EBD25E006AA00DD6C28 /* RightViewController.swift in Sources */, 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | }; 353 | D8909E8625E005D900DD6C28 /* Sources */ = { 354 | isa = PBXSourcesBuildPhase; 355 | buildActionMask = 2147483647; 356 | files = ( 357 | D8909E8F25E005D900DD6C28 /* GYSideDemoTests.swift in Sources */, 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | }; 361 | D8909E9125E005D900DD6C28 /* Sources */ = { 362 | isa = PBXSourcesBuildPhase; 363 | buildActionMask = 2147483647; 364 | files = ( 365 | D8909E9A25E005D900DD6C28 /* GYSideDemoUITests.swift in Sources */, 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | /* End PBXSourcesBuildPhase section */ 370 | 371 | /* Begin PBXTargetDependency section */ 372 | D8909E8C25E005D900DD6C28 /* PBXTargetDependency */ = { 373 | isa = PBXTargetDependency; 374 | target = D8909E7325E005D500DD6C28 /* GYSideDemo */; 375 | targetProxy = D8909E8B25E005D900DD6C28 /* PBXContainerItemProxy */; 376 | }; 377 | D8909E9725E005D900DD6C28 /* PBXTargetDependency */ = { 378 | isa = PBXTargetDependency; 379 | target = D8909E7325E005D500DD6C28 /* GYSideDemo */; 380 | targetProxy = D8909E9625E005D900DD6C28 /* PBXContainerItemProxy */; 381 | }; 382 | /* End PBXTargetDependency section */ 383 | 384 | /* Begin PBXVariantGroup section */ 385 | D8909E7D25E005D500DD6C28 /* Main.storyboard */ = { 386 | isa = PBXVariantGroup; 387 | children = ( 388 | D8909E7E25E005D500DD6C28 /* Base */, 389 | ); 390 | name = Main.storyboard; 391 | sourceTree = ""; 392 | }; 393 | D8909E8225E005D900DD6C28 /* LaunchScreen.storyboard */ = { 394 | isa = PBXVariantGroup; 395 | children = ( 396 | D8909E8325E005D900DD6C28 /* Base */, 397 | ); 398 | name = LaunchScreen.storyboard; 399 | sourceTree = ""; 400 | }; 401 | /* End PBXVariantGroup section */ 402 | 403 | /* Begin XCBuildConfiguration section */ 404 | D8909E9C25E005D900DD6C28 /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | ALWAYS_SEARCH_USER_PATHS = NO; 408 | CLANG_ANALYZER_NONNULL = YES; 409 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 410 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 411 | CLANG_CXX_LIBRARY = "libc++"; 412 | CLANG_ENABLE_MODULES = YES; 413 | CLANG_ENABLE_OBJC_ARC = YES; 414 | CLANG_ENABLE_OBJC_WEAK = YES; 415 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 416 | CLANG_WARN_BOOL_CONVERSION = YES; 417 | CLANG_WARN_COMMA = YES; 418 | CLANG_WARN_CONSTANT_CONVERSION = YES; 419 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 420 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 421 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 422 | CLANG_WARN_EMPTY_BODY = YES; 423 | CLANG_WARN_ENUM_CONVERSION = YES; 424 | CLANG_WARN_INFINITE_RECURSION = YES; 425 | CLANG_WARN_INT_CONVERSION = YES; 426 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 427 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 428 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 429 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 430 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 431 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 432 | CLANG_WARN_STRICT_PROTOTYPES = YES; 433 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 434 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 435 | CLANG_WARN_UNREACHABLE_CODE = YES; 436 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 437 | COPY_PHASE_STRIP = NO; 438 | DEBUG_INFORMATION_FORMAT = dwarf; 439 | ENABLE_STRICT_OBJC_MSGSEND = YES; 440 | ENABLE_TESTABILITY = YES; 441 | GCC_C_LANGUAGE_STANDARD = gnu11; 442 | GCC_DYNAMIC_NO_PIC = NO; 443 | GCC_NO_COMMON_BLOCKS = YES; 444 | GCC_OPTIMIZATION_LEVEL = 0; 445 | GCC_PREPROCESSOR_DEFINITIONS = ( 446 | "DEBUG=1", 447 | "$(inherited)", 448 | ); 449 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 450 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 451 | GCC_WARN_UNDECLARED_SELECTOR = YES; 452 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 453 | GCC_WARN_UNUSED_FUNCTION = YES; 454 | GCC_WARN_UNUSED_VARIABLE = YES; 455 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 456 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 457 | MTL_FAST_MATH = YES; 458 | ONLY_ACTIVE_ARCH = YES; 459 | SDKROOT = iphoneos; 460 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 461 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 462 | }; 463 | name = Debug; 464 | }; 465 | D8909E9D25E005D900DD6C28 /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | ALWAYS_SEARCH_USER_PATHS = NO; 469 | CLANG_ANALYZER_NONNULL = YES; 470 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 471 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 472 | CLANG_CXX_LIBRARY = "libc++"; 473 | CLANG_ENABLE_MODULES = YES; 474 | CLANG_ENABLE_OBJC_ARC = YES; 475 | CLANG_ENABLE_OBJC_WEAK = YES; 476 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 477 | CLANG_WARN_BOOL_CONVERSION = YES; 478 | CLANG_WARN_COMMA = YES; 479 | CLANG_WARN_CONSTANT_CONVERSION = YES; 480 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 481 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 482 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 483 | CLANG_WARN_EMPTY_BODY = YES; 484 | CLANG_WARN_ENUM_CONVERSION = YES; 485 | CLANG_WARN_INFINITE_RECURSION = YES; 486 | CLANG_WARN_INT_CONVERSION = YES; 487 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 488 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 489 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 490 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 491 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 492 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 493 | CLANG_WARN_STRICT_PROTOTYPES = YES; 494 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 495 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 496 | CLANG_WARN_UNREACHABLE_CODE = YES; 497 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 498 | COPY_PHASE_STRIP = NO; 499 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 500 | ENABLE_NS_ASSERTIONS = NO; 501 | ENABLE_STRICT_OBJC_MSGSEND = YES; 502 | GCC_C_LANGUAGE_STANDARD = gnu11; 503 | GCC_NO_COMMON_BLOCKS = YES; 504 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 505 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 506 | GCC_WARN_UNDECLARED_SELECTOR = YES; 507 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 508 | GCC_WARN_UNUSED_FUNCTION = YES; 509 | GCC_WARN_UNUSED_VARIABLE = YES; 510 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 511 | MTL_ENABLE_DEBUG_INFO = NO; 512 | MTL_FAST_MATH = YES; 513 | SDKROOT = iphoneos; 514 | SWIFT_COMPILATION_MODE = wholemodule; 515 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 516 | VALIDATE_PRODUCT = YES; 517 | }; 518 | name = Release; 519 | }; 520 | D8909E9F25E005D900DD6C28 /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | baseConfigurationReference = 3F22BF64783115265BC939F1 /* Pods-GYSideDemo.debug.xcconfig */; 523 | buildSettings = { 524 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 525 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 526 | CODE_SIGN_STYLE = Automatic; 527 | INFOPLIST_FILE = GYSideDemo/Info.plist; 528 | LD_RUNPATH_SEARCH_PATHS = ( 529 | "$(inherited)", 530 | "@executable_path/Frameworks", 531 | ); 532 | PRODUCT_BUNDLE_IDENTIFIER = com.gy.GYSideDemo; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | SWIFT_VERSION = 5.0; 535 | TARGETED_DEVICE_FAMILY = "1,2"; 536 | }; 537 | name = Debug; 538 | }; 539 | D8909EA025E005D900DD6C28 /* Release */ = { 540 | isa = XCBuildConfiguration; 541 | baseConfigurationReference = 2815CA7619E4118980D24C0F /* Pods-GYSideDemo.release.xcconfig */; 542 | buildSettings = { 543 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 544 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 545 | CODE_SIGN_STYLE = Automatic; 546 | INFOPLIST_FILE = GYSideDemo/Info.plist; 547 | LD_RUNPATH_SEARCH_PATHS = ( 548 | "$(inherited)", 549 | "@executable_path/Frameworks", 550 | ); 551 | PRODUCT_BUNDLE_IDENTIFIER = com.gy.GYSideDemo; 552 | PRODUCT_NAME = "$(TARGET_NAME)"; 553 | SWIFT_VERSION = 5.0; 554 | TARGETED_DEVICE_FAMILY = "1,2"; 555 | }; 556 | name = Release; 557 | }; 558 | D8909EA225E005D900DD6C28 /* Debug */ = { 559 | isa = XCBuildConfiguration; 560 | buildSettings = { 561 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 562 | BUNDLE_LOADER = "$(TEST_HOST)"; 563 | CODE_SIGN_STYLE = Automatic; 564 | INFOPLIST_FILE = GYSideDemoTests/Info.plist; 565 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 566 | LD_RUNPATH_SEARCH_PATHS = ( 567 | "$(inherited)", 568 | "@executable_path/Frameworks", 569 | "@loader_path/Frameworks", 570 | ); 571 | PRODUCT_BUNDLE_IDENTIFIER = com.gy.GYSideDemoTests; 572 | PRODUCT_NAME = "$(TARGET_NAME)"; 573 | SWIFT_VERSION = 5.0; 574 | TARGETED_DEVICE_FAMILY = "1,2"; 575 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GYSideDemo.app/GYSideDemo"; 576 | }; 577 | name = Debug; 578 | }; 579 | D8909EA325E005D900DD6C28 /* Release */ = { 580 | isa = XCBuildConfiguration; 581 | buildSettings = { 582 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 583 | BUNDLE_LOADER = "$(TEST_HOST)"; 584 | CODE_SIGN_STYLE = Automatic; 585 | INFOPLIST_FILE = GYSideDemoTests/Info.plist; 586 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 587 | LD_RUNPATH_SEARCH_PATHS = ( 588 | "$(inherited)", 589 | "@executable_path/Frameworks", 590 | "@loader_path/Frameworks", 591 | ); 592 | PRODUCT_BUNDLE_IDENTIFIER = com.gy.GYSideDemoTests; 593 | PRODUCT_NAME = "$(TARGET_NAME)"; 594 | SWIFT_VERSION = 5.0; 595 | TARGETED_DEVICE_FAMILY = "1,2"; 596 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GYSideDemo.app/GYSideDemo"; 597 | }; 598 | name = Release; 599 | }; 600 | D8909EA525E005D900DD6C28 /* Debug */ = { 601 | isa = XCBuildConfiguration; 602 | buildSettings = { 603 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 604 | CODE_SIGN_STYLE = Automatic; 605 | INFOPLIST_FILE = GYSideDemoUITests/Info.plist; 606 | LD_RUNPATH_SEARCH_PATHS = ( 607 | "$(inherited)", 608 | "@executable_path/Frameworks", 609 | "@loader_path/Frameworks", 610 | ); 611 | PRODUCT_BUNDLE_IDENTIFIER = com.gy.GYSideDemoUITests; 612 | PRODUCT_NAME = "$(TARGET_NAME)"; 613 | SWIFT_VERSION = 5.0; 614 | TARGETED_DEVICE_FAMILY = "1,2"; 615 | TEST_TARGET_NAME = GYSideDemo; 616 | }; 617 | name = Debug; 618 | }; 619 | D8909EA625E005D900DD6C28 /* Release */ = { 620 | isa = XCBuildConfiguration; 621 | buildSettings = { 622 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 623 | CODE_SIGN_STYLE = Automatic; 624 | INFOPLIST_FILE = GYSideDemoUITests/Info.plist; 625 | LD_RUNPATH_SEARCH_PATHS = ( 626 | "$(inherited)", 627 | "@executable_path/Frameworks", 628 | "@loader_path/Frameworks", 629 | ); 630 | PRODUCT_BUNDLE_IDENTIFIER = com.gy.GYSideDemoUITests; 631 | PRODUCT_NAME = "$(TARGET_NAME)"; 632 | SWIFT_VERSION = 5.0; 633 | TARGETED_DEVICE_FAMILY = "1,2"; 634 | TEST_TARGET_NAME = GYSideDemo; 635 | }; 636 | name = Release; 637 | }; 638 | /* End XCBuildConfiguration section */ 639 | 640 | /* Begin XCConfigurationList section */ 641 | D8909E6F25E005D500DD6C28 /* Build configuration list for PBXProject "GYSideDemo" */ = { 642 | isa = XCConfigurationList; 643 | buildConfigurations = ( 644 | D8909E9C25E005D900DD6C28 /* Debug */, 645 | D8909E9D25E005D900DD6C28 /* Release */, 646 | ); 647 | defaultConfigurationIsVisible = 0; 648 | defaultConfigurationName = Release; 649 | }; 650 | D8909E9E25E005D900DD6C28 /* Build configuration list for PBXNativeTarget "GYSideDemo" */ = { 651 | isa = XCConfigurationList; 652 | buildConfigurations = ( 653 | D8909E9F25E005D900DD6C28 /* Debug */, 654 | D8909EA025E005D900DD6C28 /* Release */, 655 | ); 656 | defaultConfigurationIsVisible = 0; 657 | defaultConfigurationName = Release; 658 | }; 659 | D8909EA125E005D900DD6C28 /* Build configuration list for PBXNativeTarget "GYSideDemoTests" */ = { 660 | isa = XCConfigurationList; 661 | buildConfigurations = ( 662 | D8909EA225E005D900DD6C28 /* Debug */, 663 | D8909EA325E005D900DD6C28 /* Release */, 664 | ); 665 | defaultConfigurationIsVisible = 0; 666 | defaultConfigurationName = Release; 667 | }; 668 | D8909EA425E005D900DD6C28 /* Build configuration list for PBXNativeTarget "GYSideDemoUITests" */ = { 669 | isa = XCConfigurationList; 670 | buildConfigurations = ( 671 | D8909EA525E005D900DD6C28 /* Debug */, 672 | D8909EA625E005D900DD6C28 /* Release */, 673 | ); 674 | defaultConfigurationIsVisible = 0; 675 | defaultConfigurationName = Release; 676 | }; 677 | /* End XCConfigurationList section */ 678 | }; 679 | rootObject = D8909E6C25E005D500DD6C28 /* Project object */; 680 | } 681 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // GYSideDemo 4 | // 5 | // Created by y g on 2021/2/19. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | UISupportedInterfaceOrientations~ipad 59 | 60 | UIInterfaceOrientationPortrait 61 | UIInterfaceOrientationPortraitUpsideDown 62 | UIInterfaceOrientationLandscapeLeft 63 | UIInterfaceOrientationLandscapeRight 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/LeftViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeftViewController.swift 3 | // GYSide 4 | // 5 | // Created by 高源 on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import GYSide 11 | 12 | class LeftViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 13 | 14 | var titleArray = ["present出一个控制器","push到一个控制器"]; 15 | var tableView:UITableView! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | self.configSubviews() 20 | // Do any additional setup after loading the view, typically from a nib. 21 | } 22 | 23 | override func viewWillAppear(_ animated: Bool) { 24 | super.viewWillAppear(animated) 25 | } 26 | 27 | 28 | func configSubviews() { 29 | self.view.backgroundColor = UIColor.white 30 | tableView = UITableView.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: self.view.bounds.height) , style:.plain) 31 | tableView.delegate = self 32 | tableView.dataSource = self 33 | tableView.tableFooterView = UIView.init() 34 | tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: "id") 35 | self.view.addSubview(tableView) 36 | if #available(iOS 11.0, *) { 37 | tableView.contentInsetAdjustmentBehavior = .never 38 | } 39 | let header = UIImageView.init(frame: CGRect.init(x: 0, y: 0, width: self.view.bounds.size.width, height: 180)) 40 | header.backgroundColor = UIColor.red 41 | header.contentMode = .scaleAspectFill 42 | header.clipsToBounds = true 43 | header.image = UIImage.init(named: "2.jpeg") 44 | tableView.tableHeaderView = header 45 | } 46 | 47 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 48 | return titleArray.count; 49 | } 50 | 51 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 52 | let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "id")! 53 | cell.textLabel?.text = titleArray[indexPath.row] 54 | return cell 55 | } 56 | 57 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 58 | switch indexPath.row { 59 | case 0: 60 | DispatchQueue.main.async { 61 | self.gy_sidePresentViewController(viewController: PresentViewController()) 62 | } 63 | break 64 | case 1: 65 | self.gy_sidePushViewController(viewController: PresentViewController()) 66 | break 67 | default: 68 | break 69 | } 70 | } 71 | 72 | override func didReceiveMemoryWarning() { 73 | super.didReceiveMemoryWarning() 74 | // Dispose of any resources that can be recreated. 75 | } 76 | 77 | deinit { 78 | print( NSStringFromClass(self.classForCoder) + " ----> 销毁了") 79 | } 80 | 81 | 82 | /* 83 | // MARK: - Navigation 84 | 85 | // In a storyboard-based application, you will often want to do a little preparation before navigation 86 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 87 | // Get the new view controller using segue.destinationViewController. 88 | // Pass the selected object to the new view controller. 89 | } 90 | */ 91 | 92 | } 93 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/PresentViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PresentViewController.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/31. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PresentViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | self.view.backgroundColor = UIColor.white 16 | let imgView = UIImageView.init(frame: self.view.bounds) 17 | imgView.image = UIImage.init(named: "3.jpeg") 18 | self.view.addSubview(imgView) 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 23 | self.dismiss(animated: true, completion: nil) 24 | } 25 | 26 | override func didReceiveMemoryWarning() { 27 | super.didReceiveMemoryWarning() 28 | // Dispose of any resources that can be recreated. 29 | } 30 | 31 | 32 | /* 33 | // MARK: - Navigation 34 | 35 | // In a storyboard-based application, you will often want to do a little preparation before navigation 36 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 37 | // Get the new view controller using segue.destinationViewController. 38 | // Pass the selected object to the new view controller. 39 | } 40 | */ 41 | 42 | } 43 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/RightViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RightViewController.swift 3 | // GYSide 4 | // 5 | // Created by 高源 on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class RightViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | self.view.backgroundColor = UIColor.white 17 | 18 | 19 | self.view.backgroundColor = UIColor.white 20 | let imgView = UIImageView.init(frame: self.view.bounds) 21 | imgView.image = UIImage.init(named: "1.jpeg") 22 | self.view.addSubview(imgView) 23 | 24 | 25 | // Do any additional setup after loading the view. 26 | } 27 | 28 | override func didReceiveMemoryWarning() { 29 | super.didReceiveMemoryWarning() 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | 34 | deinit { 35 | print( NSStringFromClass(self.classForCoder) + " ----> 销毁了") 36 | } 37 | 38 | /* 39 | // MARK: - Navigation 40 | 41 | // In a storyboard-based application, you will often want to do a little preparation before navigation 42 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 43 | // Get the new view controller using segue.destinationViewController. 44 | // Pass the selected object to the new view controller. 45 | } 46 | */ 47 | 48 | } 49 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // GYSideDemo 4 | // 5 | // Created by y g on 2021/2/19. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | guard let _ = (scene as? UIWindowScene) else { return } 20 | } 21 | 22 | func sceneDidDisconnect(_ scene: UIScene) { 23 | // Called as the scene is being released by the system. 24 | // This occurs shortly after the scene enters the background, or when its session is discarded. 25 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | // Called when the scene has moved from an inactive state to an active state. 31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 32 | } 33 | 34 | func sceneWillResignActive(_ scene: UIScene) { 35 | // Called when the scene will move from an active state to an inactive state. 36 | // This may occur due to temporary interruptions (ex. an incoming phone call). 37 | } 38 | 39 | func sceneWillEnterForeground(_ scene: UIScene) { 40 | // Called as the scene transitions from the background to the foreground. 41 | // Use this method to undo the changes made on entering the background. 42 | } 43 | 44 | func sceneDidEnterBackground(_ scene: UIScene) { 45 | // Called as the scene transitions from the foreground to the background. 46 | // Use this method to save data, release shared resources, and store enough scene-specific state information 47 | // to restore the scene back to its current state. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // GYSide 4 | // 5 | // Created by gaoyuan on 2018/1/29. 6 | // Copyright © 2018年 gaoyuan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | var titleArray = ["左出平移","左出遮盖","左出缩放","右出平移","右出遮盖","右出缩放"]; 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | configSubviews() 18 | // Do any additional setup after loading the view, typically from a nib. 19 | } 20 | 21 | func configSubviews() { 22 | 23 | view.backgroundColor = UIColor.white 24 | let imgView = UIImageView.init(frame: self.view.bounds) 25 | imgView.image = UIImage.init(named: "4.jpeg") 26 | view.addSubview(imgView) 27 | 28 | let top:Int = Int(UIApplication.shared.statusBarFrame.height + (self.navigationController?.navigationBar.bounds.height)!) 29 | let tableView = UITableView(frame: CGRect(x: 0, y: top, width: Int(view.bounds.width), height: Int(view.bounds.height)-top), style:.plain) 30 | tableView.backgroundView = imgView; 31 | tableView.delegate = self 32 | tableView.dataSource = self 33 | tableView.tableFooterView = UIView.init() 34 | tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: "id") 35 | if #available(iOS 11.0, *) { 36 | tableView.contentInsetAdjustmentBehavior = .never 37 | } 38 | self.view.addSubview(tableView) 39 | 40 | 41 | // let vc = LeftViewController() 42 | // gy_registGestureShowSide { (direction) in 43 | // if direction == .left { 44 | // self.gy_showSide(configuration: { (config) in 45 | // config.animationType = .zoom 46 | // }, viewController: vc) 47 | // }else { 48 | // self.gy_showSide(configuration: { (config) in 49 | // config.direction = .right 50 | // }, viewController: vc) 51 | // } 52 | // } 53 | } 54 | 55 | deinit { 56 | print( NSStringFromClass(self.classForCoder) + " 销毁了") 57 | } 58 | 59 | override func didReceiveMemoryWarning() { 60 | super.didReceiveMemoryWarning() 61 | // Dispose of any resources that can be recreated. 62 | } 63 | 64 | } 65 | 66 | 67 | extension ViewController:UITableViewDataSource { 68 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 69 | titleArray.count; 70 | } 71 | 72 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 73 | let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "id")! 74 | cell.textLabel?.text = titleArray[indexPath.row] 75 | cell.accessoryType = .disclosureIndicator; 76 | return cell 77 | } 78 | } 79 | 80 | extension ViewController:UITableViewDelegate { 81 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 82 | if indexPath.row == 0 { //左出平移 83 | let vc = LeftViewController() 84 | gy_showSide({ (config) in 85 | 86 | },vc) 87 | }else if indexPath.row == 1 { //左出遮罩 88 | let vc = LeftViewController() 89 | gy_showSide({ (config) in 90 | config.animationType = .translationMask 91 | config.sideRelative = 0.6 92 | // config.timeInterval = 3; 93 | }, vc) 94 | }else if indexPath.row == 2 { //左出缩放 95 | let vc = LeftViewController.init() 96 | gy_showSide({ (config) in 97 | config.animationType = .zoom // 侧边来出来的动画方式 98 | config.timeInterval = 0.3 // 执行动画的时长 默认0.3 99 | config.direction = .left // 侧边来出来的的方向 默认从左边出来 100 | config.maskAlpha = 0.5 // 遮罩视图的透明度 默认0.5 101 | config.sideRelative = 0.7 // 侧边栏相对屏幕宽度比例 默认0.7 102 | config.zoomOffsetRelative = 0.5 // 缩放模式时 缩放控制器的view偏移相对屏幕宽度比例 默认0.5 103 | config.zoomRelative = 0.7 // 缩放模式时缩放的比例 默认0.7 104 | }, vc) 105 | }else if indexPath.row == 3 { //右出平移 106 | let vc = RightViewController() 107 | gy_showSide({ (config) in 108 | config.direction = .right 109 | }, vc) 110 | }else if indexPath.row == 4 { //右出遮罩 111 | let vc = RightViewController() 112 | gy_showSide({ (config) in 113 | config.direction = .right 114 | config.animationType = .translationMask 115 | }, vc) 116 | }else if indexPath.row == 5 { //右出缩放 117 | let vc = RightViewController() 118 | gy_showSide({ (config) in 119 | config.direction = .right 120 | config.animationType = .zoom 121 | }, vc) 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/img/1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuan-gao/GYSide/2b5e2500a103a82383aaf10f91a93b5cd1ae3938/GYSideDemo/GYSideDemo/img/1.jpeg -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/img/2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuan-gao/GYSide/2b5e2500a103a82383aaf10f91a93b5cd1ae3938/GYSideDemo/GYSideDemo/img/2.jpeg -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/img/3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuan-gao/GYSide/2b5e2500a103a82383aaf10f91a93b5cd1ae3938/GYSideDemo/GYSideDemo/img/3.jpeg -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemo/img/4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuan-gao/GYSide/2b5e2500a103a82383aaf10f91a93b5cd1ae3938/GYSideDemo/GYSideDemo/img/4.jpeg -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemoTests/GYSideDemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSideDemoTests.swift 3 | // GYSideDemoTests 4 | // 5 | // Created by y g on 2021/2/19. 6 | // 7 | 8 | import XCTest 9 | @testable import GYSideDemo 10 | 11 | class GYSideDemoTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemoUITests/GYSideDemoUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GYSideDemoUITests.swift 3 | // GYSideDemoUITests 4 | // 5 | // Created by y g on 2021/2/19. 6 | // 7 | 8 | import XCTest 9 | 10 | class GYSideDemoUITests: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | 15 | // In UI tests it is usually best to stop immediately when a failure occurs. 16 | continueAfterFailure = false 17 | 18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 19 | } 20 | 21 | override func tearDownWithError() throws { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | func testExample() throws { 26 | // UI tests must launch the application that they test. 27 | let app = XCUIApplication() 28 | app.launch() 29 | 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | func testLaunchPerformance() throws { 35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { 36 | // This measures how long it takes to launch your application. 37 | measure(metrics: [XCTApplicationLaunchMetric()]) { 38 | XCUIApplication().launch() 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /GYSideDemo/GYSideDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /GYSideDemo/Podfile: -------------------------------------------------------------------------------- 1 | 2 | target 'GYSideDemo' do 3 | #pod 'LookinServer', :configurations => ['Debug'] 4 | pod 'GYSide', :path => '../' 5 | end 6 | -------------------------------------------------------------------------------- /GYSideDemo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - GYSide (0.0.4) 3 | 4 | DEPENDENCIES: 5 | - GYSide (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | GYSide: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | GYSide: b84a16d6cd66cc678f8f21b2f013ec5d9edc292f 13 | 14 | PODFILE CHECKSUM: 08b24ee9743b061d47013603c70c44ad776bb0dd 15 | 16 | COCOAPODS: 1.9.2 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 yuan-gao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GYSide安装 2 | 3 | ## CocoaPods 4 | - 在 Podfile 中添加 `pod 'GYSide'` 5 | - 执行 `pod setup` 更新本地pod库 6 | - 执行 `pod install` 或 `pod update` 安装 7 | 8 | ## 效果 9 | 10 | ![](http://upload-images.jianshu.io/upload_images/959455-3acdcba52c033df9.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 11 | 12 | ## 使用 13 | 14 | - 显示侧边栏 15 | 16 | ``` 17 | let vc = LeftViewController.init() 18 | gy_showSide(configuration: { (config) in 19 | config.animationType = .zoom // 侧边来出来的动画方式 20 | config.timeInterval = 0.3 // 执行动画的时长 默认0.3 21 | config.direction = .left // 侧边来出来的的方向 默认从左边出来 22 | config.maskAlpha = 0.5 // 遮罩视图的透明度 默认0.5 23 | config.sideRelative = 0.7 // 侧边栏相对屏幕宽度比例 默认0.7 24 | config.zoomOffsetRelative = 0.5 // 缩放模式时 缩放控制器的view偏移相对屏幕宽度比例 默认0.5 25 | config.zoomRelative = 0.7 // 缩放模式时缩放的比例 默认0.7 26 | }, viewController: vc) 27 | ``` 28 | 29 | - 从侧边栏push控制器 30 | 31 | ``` 32 | self.gy_sidePushViewController(viewController: UIViewController()) 33 | ``` 34 | 35 | - 从侧边栏present控制器 36 | 37 | ``` 38 | self.gy_sidePresentViewController(viewController: UIViewController()) 39 | ``` --------------------------------------------------------------------------------