You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

145 lines
5.3 KiB

// The MIT License (MIT)
//
// Copyright (c) 2016 Luke Zhao <me@lkzhao.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import UIKit
extension HeroTransition {
open func complete(finished: Bool) {
if state == .notified {
forceFinishing = finished
}
guard state == .animating || state == .starting else { return }
defer {
transitionContext = nil
fromViewController = nil
toViewController = nil
inNavigationController = false
inTabBarController = false
forceNotInteractive = false
animatingToViews.removeAll()
animatingFromViews.removeAll()
progressUpdateObservers = nil
transitionContainer = nil
completionCallback = nil
forceFinishing = nil
container = nil
startingProgress = nil
processors.removeAll()
animators.removeAll()
plugins.removeAll()
context = nil
progress = 0
totalDuration = 0
state = .possible
}
state = .completing
progressRunner.stop()
context.clean()
if let toView = toView, let fromView = fromView {
if finished && isPresenting && toOverFullScreen {
// finished presenting a overFullScreen VC
context.unhide(rootView: toView)
context.removeSnapshots(rootView: toView)
context.storeViewAlpha(rootView: fromView)
fromViewController?.hero.storedSnapshot = container
container.superview?.addSubview(fromView)
fromView.addSubview(container)
} else if !finished && !isPresenting && fromOverFullScreen {
// cancelled dismissing a overFullScreen VC
context.unhide(rootView: fromView)
context.removeSnapshots(rootView: fromView)
context.storeViewAlpha(rootView: toView)
toViewController?.hero.storedSnapshot = container
container.superview?.addSubview(toView)
toView.addSubview(container)
} else {
context.unhideAll()
context.removeAllSnapshots()
}
// move fromView & toView back from our container back to the one supplied by UIKit
if (toOverFullScreen && finished) || (fromOverFullScreen && !finished) {
transitionContainer?.addSubview(finished ? fromView : toView)
}
transitionContainer?.addSubview(finished ? toView : fromView)
if isPresenting != finished, !inContainerController, transitionContext != nil {
// only happens when present a .overFullScreen VC
// bug: http://openradar.appspot.com/radar?id=5320103646199808
UIApplication.shared.keyWindow?.addSubview(isPresenting ? fromView : toView)
}
}
if container.superview == transitionContainer {
container.removeFromSuperview()
}
for animator in animators {
animator.clean()
}
transitionContainer?.isUserInteractionEnabled = true
completionCallback?(finished)
// https://github.com/lkzhao/Hero/issues/354
// tabbar not responding after pushing a view controller with hideBottomBarWhenPushed
// this is due to iOS adding a few extra animation to the tabbar but they are not removed when
// the transition completes. Possibly another iOS bug. let me know if you have better work around.
if finished {
toViewController?.tabBarController?.tabBar.layer.removeAllAnimations()
} else {
fromViewController?.tabBarController?.tabBar.layer.removeAllAnimations()
}
if finished {
if let fvc = fromViewController, let tvc = toViewController {
closureProcessForHeroDelegate(vc: fvc) {
$0.heroDidEndAnimatingTo?(viewController: tvc)
$0.heroDidEndTransition?()
}
closureProcessForHeroDelegate(vc: tvc) {
$0.heroDidEndAnimatingFrom?(viewController: fvc)
$0.heroDidEndTransition?()
}
}
transitionContext?.finishInteractiveTransition()
} else {
if let fvc = fromViewController, let tvc = toViewController {
closureProcessForHeroDelegate(vc: fvc) {
$0.heroDidCancelAnimatingTo?(viewController: tvc)
$0.heroDidCancelTransition?()
}
closureProcessForHeroDelegate(vc: tvc) {
$0.heroDidCancelAnimatingFrom?(viewController: fvc)
$0.heroDidCancelTransition?()
}
}
transitionContext?.cancelInteractiveTransition()
}
transitionContext?.completeTransition(finished)
}
}