Skip to content

Commit

Permalink
update MenuTransition and TrolleyTransition
Browse files Browse the repository at this point in the history
  • Loading branch information
hanshuaiLoopeer committed Oct 10, 2017
1 parent e1b97ad commit af7c3cc
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 40 deletions.
4 changes: 4 additions & 0 deletions AlertTransition.xcodeproj/project.pbxproj
Expand Up @@ -12,6 +12,7 @@
790FE8121EA72C120040D499 /* DifferentAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790FE8111EA72C120040D499 /* DifferentAlertController.swift */; };
790FE8141EA72F9B0040D499 /* SnapKitAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790FE8131EA72F9B0040D499 /* SnapKitAlertController.swift */; };
790FE8161EA72FC50040D499 /* StoryboardAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790FE8151EA72FC50040D499 /* StoryboardAlertController.swift */; };
791B384E1F8CAC1500D6C0E1 /* NextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791B384D1F8CAC1500D6C0E1 /* NextViewController.swift */; };
7938B22C1EA75A8500F2D71B /* MenuPercentDrivenTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7938B22B1EA75A8500F2D71B /* MenuPercentDrivenTransition.swift */; };
793E8A071EA4CFE200BA3325 /* AlertTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 793E8A051EA4CFE200BA3325 /* AlertTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
793E8A141EA4D11200BA3325 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 793E8A131EA4D11200BA3325 /* AppDelegate.swift */; };
Expand Down Expand Up @@ -51,6 +52,7 @@
790FE8111EA72C120040D499 /* DifferentAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DifferentAlertController.swift; sourceTree = "<group>"; };
790FE8131EA72F9B0040D499 /* SnapKitAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SnapKitAlertController.swift; path = Alerts/SnapKitAlertController.swift; sourceTree = "<group>"; };
790FE8151EA72FC50040D499 /* StoryboardAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StoryboardAlertController.swift; path = Alerts/StoryboardAlertController.swift; sourceTree = "<group>"; };
791B384D1F8CAC1500D6C0E1 /* NextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextViewController.swift; sourceTree = "<group>"; };
7938B22B1EA75A8500F2D71B /* MenuPercentDrivenTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MenuPercentDrivenTransition.swift; path = Transitions/MenuTransition/MenuPercentDrivenTransition.swift; sourceTree = "<group>"; };
793E8A021EA4CFE200BA3325 /* AlertTransition.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AlertTransition.framework; sourceTree = BUILT_PRODUCTS_DIR; };
793E8A051EA4CFE200BA3325 /* AlertTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AlertTransition.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -187,6 +189,7 @@
79474AA91EA764EC00873736 /* TrolleyController.swift */,
79474AAB1EA7702600873736 /* BackgroundTypeController.swift */,
79962C0A1EA77ED80046B631 /* BubbleController.swift */,
791B384D1F8CAC1500D6C0E1 /* NextViewController.swift */,
);
path = AlertTransitionDemo;
sourceTree = "<group>";
Expand Down Expand Up @@ -425,6 +428,7 @@
buildActionMask = 2147483647;
files = (
79474AA61EA75E7100873736 /* MenuController.swift in Sources */,
791B384E1F8CAC1500D6C0E1 /* NextViewController.swift in Sources */,
793E8A381EA5B98E00BA3325 /* EasyTransitionController.swift in Sources */,
793E8A491EA602B600BA3325 /* EasyStoryboardController.swift in Sources */,
79962C181EA7906D0046B631 /* SpriteRender.swift in Sources */,
Expand Down
8 changes: 6 additions & 2 deletions AlertTransition/AlertTransition.swift
Expand Up @@ -48,6 +48,7 @@ open class AlertTransition: NSObject {
public var presentationControllerType: UIPresentationController.Type = PresentationController.self
/// The InteractionTransition initialize from interactionTransitionType at suitable time
public internal(set) var interactionTransition: PercentDrivenInteractiveTransition?
public internal(set) var presentationController: PresentationController?

/// The alert controller
public internal(set) weak var toController: UIViewController!
Expand Down Expand Up @@ -96,8 +97,11 @@ extension AlertTransition: UIViewControllerTransitioningDelegate {
}

open func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
let presentationController = presentationControllerType.init(presentedViewController: presented, presenting: presenting)
(presentationController as? PresentationController)?.transition = self
let presentationController: UIPresentationController = presentationControllerType.init(presentedViewController: presented, presenting: presenting)
if let controller = presentationController as? PresentationController {
controller.transition = self
self.presentationController = controller
}
return presentationController
}

Expand Down
6 changes: 5 additions & 1 deletion AlertTransition/PresentationController.swift
Expand Up @@ -16,6 +16,9 @@ open class PresentationController: UIPresentationController {
/// The background view, initialized when presentationTransitionWillBegin, inserted to view hierarchy when containerViewWillLayoutSubviews
public fileprivate(set) var maskView: UIView?

/// Call showMaskView()、hideMaskView() manually, Usually when PercentDrivenInteractiveTransition
public var manualMaskAnimation = false

private var deviceOrientation = UIDeviceOrientation.portrait

open override var frameOfPresentedViewInContainerView: CGRect {
Expand All @@ -40,13 +43,14 @@ open class PresentationController: UIPresentationController {
}

open override func dismissalTransitionWillBegin() {
guard !manualMaskAnimation else { return }
UIView.animate(withDuration: transition!.duration) {
self.hideMaskView()
}
}

override open func containerViewWillLayoutSubviews() {
if let view = maskView, view.superview == nil {
if let view = maskView, view.superview == nil, !manualMaskAnimation {
containerView?.insertSubview(view, at: 0)

UIView.animate(withDuration: transition!.duration, animations: {
Expand Down
69 changes: 41 additions & 28 deletions AlertTransition/Transitions/MenuTransition/MenuTransition.swift
Expand Up @@ -10,42 +10,37 @@ import UIKit

public class MenuTransition: AlertTransition {

public internal(set) var forgroundMask: UIView?
public internal(set) var originSuperView: UIView?

public override init(from controller: UIViewController?) {
super.init(from: controller)
interactionTransitionType = MenuPercentDrivenTransition.self
backgroundType = .color(.clear)
}

public override func performPresentedTransition(presentingView: UIView, presentedView: UIView, context: UIViewControllerContextTransitioning) {
presentationController?.manualMaskAnimation = true
originSuperView = presentingView.superview
context.containerView.addSubview(presentingView)
context.containerView.addSubview(maskView!)
(interactionTransition as? MenuPercentDrivenTransition)?.setupDismissView(view: maskView!)

if forgroundMask == nil {

forgroundMask = UIView(frame: presentingView.bounds)

if let percentDrivenTransition = interactionTransition as? MenuPercentDrivenTransition {
percentDrivenTransition.setupDismissView(view: forgroundMask!)
}

let tap = UITapGestureRecognizer(target: self, action: #selector(maskTapped(tap:)))
forgroundMask?.addGestureRecognizer(tap)
}

UIGraphicsBeginImageContextWithOptions(UIScreen.main.bounds.size, true, UIScreen.main.scale)
presentingView.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
forgroundMask?.layer.contents = image?.cgImage

context.containerView.addSubview(forgroundMask!)
presentedView.frame.origin.x = -presentedView.frame.width / 2
presentingView.frame.origin.x = 0
maskView?.frame = presentingView.frame

UIView.animate(withDuration: duration, delay: 0, options: [.curveLinear], animations: {
// HACK: If zero, the animation briefly flashes in iOS 11. UIViewPropertyAnimators (iOS 10+) may resolve this.
let delay = (interactionTransition?.isTransiting ?? false) ? duration : 0

UIView.animate(withDuration: duration, delay: delay, options: [.curveLinear], animations: {
presentedView.transform = CGAffineTransform(translationX: presentedView.frame.width / 2, y: 0)
self.forgroundMask?.transform = CGAffineTransform(translationX: presentedView.frame.width, y: 0)
presentingView.frame.origin.x = presentedView.frame.width
self.maskView?.frame = presentingView.frame
self.presentationController?.showMaskView()
}) { (complete) in
if context.transitionWasCancelled {
context.completeTransition(false)
self.originSuperView?.addSubview(presentingView)
}else{
context.completeTransition(complete)
}
Expand All @@ -54,21 +49,39 @@ public class MenuTransition: AlertTransition {

public override func performDismissedTransition(presentingView: UIView, presentedView: UIView, context: UIViewControllerContextTransitioning) {

UIView.animate(withDuration: duration, delay: 0, options: [.curveLinear], animations: {
presentedView.transform = CGAffineTransform.identity
self.forgroundMask?.transform = CGAffineTransform.identity
// HACK: If zero, the animation briefly flashes in iOS 11. UIViewPropertyAnimators (iOS 10+) may resolve this.
let delay = (interactionTransition?.isTransiting ?? false) ? duration : 0

UIView.animate(withDuration: duration, delay: delay, options: [.curveLinear], animations: {
self.dismissActions()
}) { (complete) in
if context.transitionWasCancelled {
context.completeTransition(false)
}else{
context.completeTransition(complete)
self.originSuperView?.addSubview(presentingView)
}
}
}

@objc func maskTapped(tap: UITapGestureRecognizer) {
guard shouldDismissOutside else { return }
public func dismissActions() {
toController.view.transform = CGAffineTransform.identity
fromController?.view.frame.origin.x = 0
self.maskView?.frame = fromController?.view.frame ?? CGRect.zero
self.presentationController?.hideMaskView()
}

public func push(controller: UIViewController, from navi: UINavigationController? = nil) {
guard let naviController = navi ?? (fromController as? UINavigationController) else { return }

fromController?.dismiss(animated: true, completion: nil)
CATransaction.begin()
CATransaction.setCompletionBlock( { () -> Void in
self.toController.dismiss(animated: true, completion: nil)
})
UIView.animate(withDuration: duration, animations: { () -> Void in
self.dismissActions()
})
naviController.pushViewController(controller, animated: true)
CATransaction.commit()
}
}
27 changes: 19 additions & 8 deletions AlertTransition/Transitions/TrolleyTransition.swift
Expand Up @@ -9,6 +9,11 @@
import UIKit

public class TrolleyTransition: AlertTransition {

public var m34: CGFloat = 1.0 / -6000
public var scale: CGFloat = 0.85
public var rotate: CGFloat = 15.0 * CGFloat(Double.pi)/180.0
public var zTranslate: CGFloat = -100.0

public override init(from controller: UIViewController?) {
super.init(from: controller)
Expand All @@ -17,13 +22,16 @@ public class TrolleyTransition: AlertTransition {

public override func performPresentedTransition(presentingView: UIView, presentedView: UIView, context: UIViewControllerContextTransitioning) {
presentedView.frame.origin.y = UIScreen.main.bounds.height


UIView.animate(withDuration: duration, animations: {
presentedView.transform = CGAffineTransform(translationX: 0, y: -presentedView.frame.height)
})

UIView.animate(withDuration: duration/2, animations: {
presentingView.layer.transform = self.firstTransform()
}) { (complete) in
UIView.animate(withDuration: self.duration/2, animations: {
presentingView.layer.transform = self.secondTransform()
presentedView.transform = CGAffineTransform(translationX: 0, y: -presentedView.frame.height)
}, completion: { (complete) in
context.completeTransition(complete)
})
Expand All @@ -32,8 +40,11 @@ public class TrolleyTransition: AlertTransition {

public override func performDismissedTransition(presentingView: UIView, presentedView: UIView, context: UIViewControllerContextTransitioning) {

UIView.animate(withDuration: duration/2, animations: {
UIView.animate(withDuration: duration, animations: {
presentedView.transform = CGAffineTransform.identity
})

UIView.animate(withDuration: duration/2, animations: {
presentingView.layer.transform = self.firstTransform()
}) { (complete) in
UIView.animate(withDuration: self.duration/2, animations: {
Expand All @@ -46,18 +57,18 @@ public class TrolleyTransition: AlertTransition {

private func firstTransform() -> CATransform3D {
var form = CATransform3DIdentity
form.m34 = 1.0 / -900
form = CATransform3DScale(form, 0.9, 0.9, 1)
form = CATransform3DRotate(form, 15.0 * CGFloat(Double.pi)/180.0, 1, 0, 0)
form = CATransform3DTranslate(form, 0, 0, -100.0)
form.m34 = m34
form = CATransform3DScale(form, scale, scale, 1)
form = CATransform3DRotate(form, rotate, 1, 0, 0)
form = CATransform3DTranslate(form, 0, 0, zTranslate)
return form
}

private func secondTransform() -> CATransform3D {
var form = CATransform3DIdentity
form.m34 = firstTransform().m34
form = CATransform3DTranslate(form, 0, -20, 0)
form = CATransform3DScale(form, 0.9, 0.9, 1)
form = CATransform3DScale(form, scale, scale, 1)
return form
}
}
Expand Up @@ -39,6 +39,11 @@
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
Expand Down
10 changes: 9 additions & 1 deletion AlertTransitionDemo/MainController.swift
Expand Up @@ -20,9 +20,17 @@ class MainController: UITableViewController {
title = "AlertTransition"

tableView.register(UITableViewCell.self, forCellReuseIdentifier: UITableViewCell.description())
tableView.tableFooterView = UIView()

let promptLabel = UILabel()
promptLabel.font = UIFont.systemFont(ofSize: 14)
promptLabel.textColor = UIColor.lightText
promptLabel.text = "← Swipe Screen Edges in View"
promptLabel.sizeToFit()
promptLabel.backgroundColor = .red
tableView.tableFooterView = promptLabel

let transition = MenuTransition(from: navigationController)
transition.backgroundType = .color(UIColor.black.withAlphaComponent(0.5))
menuController.at.transition = transition
}
}
Expand Down
9 changes: 9 additions & 0 deletions AlertTransitionDemo/MenuController.swift
Expand Up @@ -9,16 +9,25 @@
import UIKit
import AlertTransition


class MenuController: UIViewController, AlertFrameProtocol {

var alertFrame: CGRect {
let width = UIScreen.main.bounds.size.height / 1136 * 511
return CGRect(x: 0, y: 0, width: width, height: UIScreen.main.bounds.size.height)
}


override func viewDidLoad() {
super.viewDidLoad()

view.layer.contents = #imageLiteral(resourceName: "menu_background").cgImage

let tap = UITapGestureRecognizer(target: self, action: #selector(viewDidTapped(tap:)))
view.addGestureRecognizer(tap)
}

@objc func viewDidTapped(tap: UITapGestureRecognizer) {
(self.at.transition as? MenuTransition)?.push(controller: NextViewController())
}
}
21 changes: 21 additions & 0 deletions AlertTransitionDemo/NextViewController.swift
@@ -0,0 +1,21 @@
//
// NextViewController.swift
// AlertTransitionDemo
//
// Created by 韩帅 on 2017/10/10.
// Copyright © 2017年 Loopeer. All rights reserved.
//

import UIKit

class NextViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()

title = "NextViewController"

view.backgroundColor = .randomColor
}
}

0 comments on commit af7c3cc

Please sign in to comment.